使用python爬取12306上面所有车次数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013243986/article/details/66972705

在爬取12306之前需要做的工作就是:
1,分析请求过程
2,分析是否需要处理cookie
3,编写代码
4,测试爬取网站是否有访问次数限制
5,部署到正式服务器上
这里重点写 如何分析请求过程:
这是12306上面查询车次的界面,出发地目的地 是我们需要输入的, 如果要爬取全国的所有的车次 那就需要找到全国所有的出发地到目的地的列表.

找了 很久发现在 车次查询页面https://kyfw.12306.cn/otn/queryTrainInfo/init 有我们需要的
是以js 文件的形式 加载到页面的 ,文件很大,里面包含了 未来 45天 的车次数据, 但是这里只有出发点到终点,没有 中间站到中间站,我们可以使用这些数据 到上面的 搜索框中搜索我们需要的数据.

下载并 处理这个文件,方便后面使用:
#下载所有的车次数据  保存为 train_list.txt文件
def getTrain_list():
    requests.adapters.DEFAULT_RETRIES = 5
    response = requests.get(train_list_url, stream=True,verify=False)
    status = response.status_code
    if status == 200:
        with open('train_list.txt', 'wb') as of:
            for chunk in response.iter_content(chunk_size=102400):
                if chunk:
                    of.write(chunk)


#分析train_list.txt文件 得出火车 出发站到终点站的数据
def trainListStartToEnd():
    global station_start_end_set
    with open('train_list.txt','rb') as of:
        text=of.readline()
        tt=text.decode("utf-8")
        ss=tt.replace("},{","}\n{").replace("2017-","\n").replace("[","\n").split("\n")
        m_list=list()
        for s in ss:
            pattern = re.compile(r'\((\w+-\w+)\)')
            match = pattern.search(s)
            if match:
                m_list.append(match.group(1))
        station_start_end_set=set(m_list)


接下来分析搜索后 会发生什么事 :


先会有一个初始化的过程,初始化过程中使用到了 下面的参数,北京和上海是 我们输入的,但是目前没有站点编码



查看该页面的js时 发现 该链接中包含了 全国所有的站点对应的编码:


处理里面的站点和编码 方便后面使用:


查看cookie时 发现 在请求这个链接时 是需要发送 cookie的 ,但是这些cookie怎么来的呢!


但我把cookie清空后再请求,发现请求这个链接就可以收到 cookie


接着就是请求数据接口 :

链接中的 purpose_codes 表示票的类型 这是成人票


请求这个接口需要使用到上面初始化返回回来的cookie:


请求函数:

#利用出发站到终点站 爬取期间的列车数据
def getTrainNoList(back_date,train_date,from_station,from_station_name,to_station,to_station_name):
    post_data= {'back_train_date':back_date,
                '_json_att':"",'flag':'dc',
                'leftTicketDTO.from_station':from_station,
                'leftTicketDTO.to_station':to_station,
                'leftTicketDTO.from_station_name':from_station_name,
                'leftTicketDTO.to_station_name':to_station_name,
                'leftTicketDTO.train_date':train_date,
                'pre_step_flag':'index',
                'purpose_code':'ADULT'}

    init_resp=requests.post(init_url,data=post_data,headers=HEADERS,allow_redirects=True,verify=False)
    cookies=init_resp.cookies
    cookies.set('_jc_save_fromStation', from_station_name+','+from_station, domain='kyfw.12306.cn', path='/')
    cookies.set('_jc_save_toStation', to_station_name+','+to_station, domain='kyfw.12306.cn', path='/')
    cookies.set('_jc_save_fromDate', train_date, domain='kyfw.12306.cn', path='/')
    cookies.set('_jc_save_toDate', back_date, domain='kyfw.12306.cn', path='/')
    cookies.set('_jc_save_wfdc_flag', 'dc', domain='kyfw.12306.cn', path='/')
    url=query_url+"leftTicketDTO.train_date="+train_date+"&leftTicketDTO.from_station="+from_station+"&leftTicketDTO.to_station="+to_station+"&purpose_codes=ADULT"
    try:
        response = requests.get(url, headers=HEADERS, allow_redirects=True,cookies=cookies,verify=False,timeout=10)
        data=""
        if response.status_code==200:
            data=response.content
        data=data.decode("UTF-8")
        return data,cookies
    except  Exception as err:
        logger.exception('getTrainNoList error 获取车次列表错误 日期'+train_date+'从'+from_station_name+'到'+to_station_name+' :%s',err)
        return None,None

之后只要再对 返回的数据进行处理就可以了

技术交流可以发邮件到 zhenpeng_lin@qq.com




展开阅读全文

没有更多推荐了,返回首页