首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >12306旅游产品数据抓取:Python+API逆向分析

12306旅游产品数据抓取:Python+API逆向分析

原创
作者头像
小白学大数据
发布2025-08-05 16:49:40
发布2025-08-05 16:49:40
2170
举报

1. 引言

12306作为中国铁路官方售票平台,不仅提供火车票预订服务,还涵盖了丰富的旅游产品,如跟团游、自由行、酒店套餐等。这些数据对旅游行业分析、价格监控、竞品研究等具有重要价值。然而,12306的数据接口通常有严格的访问限制和反爬机制,直接爬取网页可能效率低下且容易被封禁。

本文将通过API逆向分析的方式,使用Python模拟合法请求,高效抓取12306旅游产品数据,并提供完整的代码实现。

2. 技术选型

2.1 Python爬虫工具

  • Requests:发送HTTP请求,获取API数据。
  • Selenium(可选):用于动态渲染页面的情况。
  • BeautifulSoup / PyQuery:解析HTML(如果涉及网页抓取)。
  • JSON / Pandas:处理和存储数据。

2.2 反爬应对策略

  • User-Agent轮换:模拟浏览器访问。
  • IP代理池:防止IP被封。
  • 请求频率控制:避免触发反爬机制。
  • Cookie/Session管理:维持登录状态(如需要)。

3. 12306旅游产品API逆向分析

3.1 分析目标

我们需要获取12306旅游产品数据,包括:

  • 旅游线路名称
  • 出发地/目的地
  • 价格
  • 行程天数
  • 产品详情页URL

3.2 寻找API接口

  1. 浏览器开发者工具(F12)
    • 打开12306旅游频道(如:https://kyfw.12306.cn/otn/)。
    • 进入Network(网络)选项卡,筛选XHRFetch请求。
    • 搜索关键词producttravellist等,找到返回JSON数据的API。
  2. 示例API(需动态分析)
    • 假设找到一个类似https://kyfw.12306.cn/otn/travel/product/list?page=1的接口。
    • 观察请求头(Headers),特别是User-AgentRefererCookie等。

3.3 模拟合法请求

12306的API通常需要:

  • Referer(来源页面)
  • Cookie(可能涉及登录态)
  • 加密参数(如_json_att,需动态获取)

我们可以用Python的requests库构造合法请求:

代码语言:txt
复制
import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
    "Cookie": "JSESSIONID=...; RAIL_EXPIRATION=...; RAIL_DEVICEID=...",  # 需替换为有效Cookie
}

url = "https://kyfw.12306.cn/otn/travel/product/list?page=1"
response = requests.get(url, headers=headers)

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print("请求失败:", response.status_code)

4. 完整爬取流程与代码实现4.1 获取Cookie(模拟登录)12306可能需要登录才能访问API,我们可以用Selenium模拟登录并提取Cookie:

代码语言:txt
复制
from selenium import webdriver
import time

def get_12306_cookie():
    driver = webdriver.Chrome()
    driver.get("https://kyfw.12306.cn/otn/resources/login.html")
    
    # 手动扫码登录(或自动填充账号密码)
    time.sleep(20)  # 留时间扫码
    
    # 获取Cookie
    cookies = driver.get_cookies()
    cookie_str = "; ".join([f"{c['name']}={c['value']}" for c in cookies])
    
    driver.quit()
    return cookie_str

cookie = get_12306_cookie()
print("获取的Cookie:", cookie)

4.2 爬取旅游产品数据

结合API分析和Cookie管理,完整爬取代码:

代码语言:txt
复制
import requests
import pandas as pd
from fake_useragent import UserAgent
import time
import random

# 代理配置
proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"

# 构造代理字典
proxies = {
    "http": f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}",
    "https": f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}",
}

def get_random_headers():
    """生成随机请求头"""
    ua = UserAgent()
    return {
        "User-Agent": ua.random,
        "Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
        "Accept": "application/json, text/javascript, */*; q=0.01",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Connection": "keep-alive",
        "X-Requested-With": "XMLHttpRequest",
    }

def fetch_12306_travel_products(page=1, max_pages=5):
    """爬取12306旅游产品数据(带代理IP)"""
    all_products = []
    base_url = "https://kyfw.12306.cn/otn/travel/product/list"
    
    for page in range(1, max_pages + 1):
        try:
            # 每次请求使用随机请求头
            headers = get_random_headers()
            headers["Cookie"] = get_12306_cookie()  # 替换为你的Cookie
            
            params = {"page": page}
            
            # 添加随机延迟(1-3秒)
            time.sleep(random.uniform(1, 3))
            
            # 发送带代理的请求
            response = requests.get(
                base_url,
                headers=headers,
                params=params,
                proxies=proxies,
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                products = data.get("data", {}).get("list", [])
                all_products.extend(products)
                print(f"✅ 成功爬取第 {page} 页,共 {len(products)} 条数据")
            else:
                print(f"❌ 第 {page} 页请求失败,状态码: {response.status_code}")
                
        except Exception as e:
            print(f"⚠️ 第 {page} 页请求异常: {str(e)}")
            continue
    
    return all_products

# 示例:获取Cookie(需替换为实际实现)
def get_12306_cookie():
    """获取12306登录Cookie(示例函数,需替换为实际实现)"""
    return "JSESSIONID=...; RAIL_EXPIRATION=...; RAIL_DEVICEID=..."

# 主程序
if __name__ == "__main__":
    print("🚀 开始爬取12306旅游产品数据...")
    
    # 爬取数据(3页示例)
    travel_data = fetch_12306_travel_products(max_pages=3)
    
    # 数据处理
    if travel_data:
        df = pd.DataFrame(travel_data)
        
        # 提取关键字段
        df = df[[
            "productName",  # 产品名称
            "fromStation",  # 出发地
            "toStation",    # 目的地
            "price",        # 价格
            "days",         # 行程天数
            "productUrl"    # 详情链接
        ]]
        
        # 保存数据
        df.to_csv("12306_travel_products.csv", index=False, encoding='utf_8_sig')
        print(f"🎉 数据已保存至 12306_travel_products.csv,共 {len(df)} 条记录")
    else:
        print("❌ 未获取到有效数据")

4.3 数据解析与存储

爬取的数据通常是JSON格式,可以用pandas整理成结构化数据:

代码语言:txt
复制
import pandas as pd

# 示例数据整理
df = pd.DataFrame(travel_data)
df = df[[
    "productName",  # 产品名称
    "fromStation",  # 出发地
    "toStation",    # 目的地
    "price",        # 价格
    "days",         # 行程天数
    "productUrl"    # 详情链接
]]
print(df.head())

5. 结论本文通过API逆向分析,使用Python高效抓取12306旅游产品数据,并提供了完整的代码实现。关键点包括:API分析:通过浏览器开发者工具找到数据接口。模拟请求:构造合法Headers和Cookie。反爬策略:使用代理IP、随机UA、请求延迟等。数据存储:用pandas整理并导出CSV。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 引言
  • 2. 技术选型
    • 2.1 Python爬虫工具
    • 2.2 反爬应对策略
  • 3. 12306旅游产品API逆向分析
    • 3.1 分析目标
    • 3.2 寻找API接口
    • 3.3 模拟合法请求
    • 4.2 爬取旅游产品数据
    • 4.3 数据解析与存储
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档