当前位置: 首页 > news >正文

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

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(网络)选项卡,筛选**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">XHR</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Fetch</font>**请求。
    • 搜索关键词**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">product</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">travel</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">list</font>**等,找到返回JSON数据的API。
  2. 示例API(需动态分析)
    • 假设找到一个类似**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">https://kyfw.12306.cn/otn/travel/product/list?page=1</font>**的接口。
    • 观察请求头(Headers),特别是**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">User-Agent</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Referer</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Cookie</font>**等。

3.3 模拟合法请求

12306的API通常需要:

  • Referer(来源页面)
  • Cookie(可能涉及登录态)
  • 加密参数(如**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">_json_att</font>**,需动态获取)

我们可以用Python的**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">requests</font>**库构造合法请求:

import requestsheaders = {"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:

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

4.2 爬取旅游产品数据

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

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()  # 替换为你的Cookieparams = {"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)}")continuereturn 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格式,可以用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">pandas</font>**整理成结构化数据:

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

5. 结论

本文通过API逆向分析,使用Python高效抓取12306旅游产品数据,并提供了完整的代码实现。关键点包括:

  1. API分析:通过浏览器开发者工具找到数据接口。
  2. 模拟请求:构造合法Headers和Cookie。
  3. 反爬策略:使用代理IP、随机UA、请求延迟等。
  4. 数据存储:用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">pandas</font>**整理并导出CSV。
http://www.dtcms.com/a/316362.html

相关文章:

  • 如何让 RAG 检索更高效?——大模型召回策略全解
  • 跨越系统孤岛:4A架构如何实现企业级一体化协同
  • 从RNN为什么长依赖遗忘到注意力机制的解决方案以及并行
  • chromedp 笔记
  • 同向双指针——滑动窗口
  • 使用公众号的消息模板给关注用户发消息
  • UNet改进(30):SageAttention在UNet中的4-Bit量化实现详解
  • UOS20操作系统关闭NUMA和透明大页(UOS20+KunPeng920)
  • mq_timedreceive系统调用及示例
  • 工业设备远程监控的 “颠覆性突破”:边缘计算网关让千里之外如在眼前
  • 【图像算法 - 09】基于深度学习的烟雾检测:从算法原理到工程实现,完整实战指南
  • 16核32G硬件服务器租用需要多少钱
  • 【Redis初阶】------单线程模型
  • Next.js SSR 实战:构建高性能新闻网站
  • C++中的泛型算法(三)
  • 智慧城市SaaS平台|市容环卫管理系统
  • 【PHP】对数据库操作:获取数据表,导出数据结构,根据条件生成SQL语句,根据条件导出SQL文件
  • nordic通过j-link rtt viewer打印日志
  • Unknown initial character set index ‘255’,Kettle连接MySQL数据库常见错误及解决方案大全
  • 心念之球:在意识的天空下
  • Gemini CLI最近更新
  • GitLab:一站式 DevOps 平台的全方位解析
  • 笔记学习杂记
  • fastgpt本地运行起来的 服务配置
  • iptables 里INPUT、OUTPUT、FORWARD 三个链(Chain)详解
  • 编程算法:技术创新与业务增长的核心引擎
  • 如何在虚拟机(Linux)安装Qt5.15.2
  • STM32 外设驱动模块一:LED 模块
  • 第13届蓝桥杯Scratch_选拔赛_初级组_真题2021年10月23日
  • 基于MATLAB实现的频域模态参数识别方法