码迷,mamicode.com
首页 > 其他好文 > 详细

最新12306票务查询抓取

时间:2020-12-04 11:04:00      阅读:4      评论:0      收藏:0      [点我收藏+]

标签:sts   set   mod   mozilla   like   strftime   点击   flag   发送   

1. 通过抓包工具发现,station.name.js这个js文件存储了所有的车站信息,

技术图片
经过对请求头的分析,发现请求的url为:https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9168,但经过测试发现station_version请求的参数对与相应的结果没有影响,因此爬取过成功直接忽略了请求参数。
抓取站台信息代码如下:

import requests


HEADERS= {
    ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36‘,
}

def get_station():
    url = ‘https://kyfw.12306.cn/otn/resources/js/framework/station_name.js‘
    res_str = requests.get(url, headers=headers).text.split(‘=‘)[-1].strip("‘")
    res_dic = {}
    for i in res_str[1:].split(‘@‘):
        res = i.split(‘|‘)
        res_dic.update({res[1]: res[2]})
    retrun res_dic

if __name__ == "__main__":
      get_station()

执行结果如下:
技术图片

2.继续分析车票信息,发现query这个请求就是查询的火车票的票务信息

技术图片
通过分析请求的url链接发现上面Cookie有很多,由于刚开始的时候我并没有使用Cookie,发现请求的响应始终获取不到正确的结果,然后清除游览器缓存的所有cookie再次点击查询查询按钮,抓包如下:
技术图片
发现只发送了2次ajax请求,但是这两次响应也都没有设置cookie,为什么会携带上了cookie信息,因此猜测发送ajax请求的时候自动生成了cookie。

3.查询cookie是如何生成的

使用search进行全局搜索(快捷键ctrl+shift+F),搜索jc_save_fromStation找到如下结果:
技术图片
然后调出Sources窗口对搜索到的js代码进行局部搜索jc_save_fromStation,发现jc_save_fromStation是jc_getcookie函数的一个参数,发现如下:
技术图片
继续对搜索到的jc_save_fromStation下入断点进行调试,发现:
技术图片
然后继续进行局部搜索jc_setcookie,发现:
技术图片,其中前两个参数就是分别对应着cookie的键和值,并且cookie的键和值是不会发生变化的,因此判断js是请求的时候生成是正确的。
使用站长工具:http://tool.chinaz.com/tools/urlencode.aspx对cookie的键进行解码:
解码之前:
技术图片
解码之后:
技术图片
发现cookie的值就是通过url编码获得到的:
_jc_save_fromStation="北京,BJP"的编码 # 出发地名称,出发地代号的urlEncode的编码
_jc_save_toStation="上海,SHH"的编码 # 目的地,目的地代号的urlEncode的编码
_jc_save_fromDate=2020-11-30 # 出发日期
_jc_save_toDate=2020-11-29 # 查询的实际时间
_jc_save_wfdc_flag=dc # dc是固定的值

完整代码实现:

import requests
import time
from urllib import parse

HEADERS = {
    ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36‘,
}


def get_station():
    url = ‘https://kyfw.12306.cn/otn/resources/js/framework/station_name.js‘
    res_str = requests.get(url, headers=HEADERS).text.split(‘=‘)[-1].strip("‘")
    res_dic = {}
    for i in res_str[1:].split(‘@‘):
        res = i.split(‘|‘)
        res_dic.update({res[1]: res[2]})
    return res_dic


def check(start_addr, end_addr, date):
    url = ‘https://kyfw.12306.cn/otn/leftTicket/query‘
    stations = get_station()
    start_addr_str = "," + stations[start_addr]
    end_addr_str = "," + stations[end_addr]
    cookie_mode =  ‘_jc_save_fromStation={}; _jc_save_toStation={}; _jc_save_fromDate={}; _jc_save_toDate={}; _jc_save_wfdc_flag=dc‘
    from_cookie = str((start_addr).encode(‘unicode_escape‘)).replace(r‘\\‘, ‘%‘).strip(r"b‘").strip("‘") + str(parse.quote(start_addr_str))
    end_cookie = str((end_addr).encode(‘unicode_escape‘)).replace(r‘\\‘, ‘%‘).strip(r"b‘").strip("‘") + parse.quote(end_addr_str)
    from_date = date
    save_date = time.strftime("%Y-%m-%d", time.localtime(time.time()))
    cookie = cookie_mode.format(from_cookie, end_cookie, from_date, save_date)
    HEADERS[‘Cookie‘] = cookie
    params = {
        ‘leftTicketDTO.train_date‘: date,
        ‘leftTicketDTO.from_station‘: start_addr_str.strip(‘,‘),
        ‘leftTicketDTO.to_station‘: end_addr_str.strip(‘,‘),
        ‘purpose_codes‘: ‘ADULT‘,
    }
    response = requests.get(url, params=params, headers=HEADERS)
    print(response.text)


check(‘北京‘, ‘上海‘, ‘2020-11-30‘)

代码结果:
技术图片
结果总算是可以正常的拿到了,具体的代码优化过程就不在这里继续写了,具体的项目可以去https://github.com/MingHao-homes/Ticket-grabbing-12306查看

最新12306票务查询抓取

标签:sts   set   mod   mozilla   like   strftime   点击   flag   发送   

原文地址:https://www.cnblogs.com/xm-python/p/14058751.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!