通過對請求頭的分析,發現請求的url爲:https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9168,但通過測試發現station_version請求的參數對與相應的結果沒有影響,所以爬取過成功直接忽略了請求參數。
抓取站臺信息代碼以下:python
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()
執行結果以下:
git
經過分析請求的url連接發現上面Cookie有不少,因爲剛開始的時候我並無使用Cookie,發現請求的響應始終獲取不到正確的結果,而後清除遊覽器緩存的全部cookie再次點擊查詢查詢按鈕,抓包以下:
發現只發送了2次ajax請求,可是這兩次響應也都沒有設置cookie,爲何會攜帶上了cookie信息,所以猜想發送ajax請求的時候自動生成了cookie。github
使用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是固定的值ajax
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查看緩存