使用python爬取12306上面所有車次資料
阿新 • • 發佈:2019-01-07
在爬取12306之前需要做的工作就是:
1,分析請求過程
2,分析是否需要處理cookie
3,編寫程式碼
4,測試爬取網站是否有訪問次數限制
5,部署到正式伺服器上
這裡重點寫 如何分析請求過程:
這是12306上面查詢車次的介面,出發地和目的地 是我們需要輸入的, 如果要爬取全國的所有的車次 那就需要找到全國所有的出發地到目的地的列表.
是以js 檔案的形式 載入到頁面的 ,檔案很大,裡面包含了 未來 45天 的車次資料, 但是這裡只有出發點到終點,沒有 中間站到中間站,我們可以使用這些資料 到上面的 搜尋框中搜索我們需要的資料.
下載並 處理這個檔案,方便後面使用:
接下來分析搜尋後 會發生什麼事 :
先會有一個初始化的過程,初始化過程中使用到了 下面的引數,北京和上海是 我們輸入的,但是目前沒有站點編碼
檢視該頁面的js時 發現 該連結中包含了 全國所有的站點對應的編碼:
處理裡面的站點和編碼 方便後面使用:
檢視cookie時 發現 在請求這個連結時 是需要傳送 cookie的 ,但是這些cookie怎麼來的呢!
但我把cookie清空後再請求,發現請求這個連結就可以收到 cookie
接著就是請求資料介面 : 連結中的 purpose_codes 表示票的型別 這是成人票
請求這個介面需要使用到上面初始化返回回來的cookie:
請求函式:
之後只要再對 返回的資料進行處理就可以了 技術交流可以發郵件到 [email protected]
是以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
之後只要再對 返回的資料進行處理就可以了 技術交流可以發郵件到 [email protected]