前言
上篇寫了12306登錄,隔了快一個月了摄乒,才準(zhǔn)備動手寫下單篇漓穿,真的要非常感謝博客園的 Asimple朋友嗤军,如果不是看到你的留言,我?guī)缀醵纪艘獙懴缕嘶挝#@一點在簡書上就不好叙赚,都沒人看/(ㄒoㄒ)/~~,剛開始寫博客僚饭,真的需要大家的鼓勵震叮,看的人多了自然有動力寫更多的,所以這一篇要給那些看過我上篇的同學(xué)們鳍鸵,尤其是這位Asimple同學(xué)苇瓣,就是為你而寫,沒錯就是這個原因偿乖。因為你讓我知道了有人在看击罪,而且用心的在看哲嘲。發(fā)了這么多感慨,其實我不是這么愛感慨的人(????)媳禁,直入主題吧眠副。
還得說一下這次我用的是Firefox瀏覽器,在上篇中說了Chrome瀏覽器的一個問題竣稽,在抓取的請求過多的情況下囱怕,前面的請求就可能看不到請求信息,最后搞得我不得不搞了個虛擬機(jī)丧枪,裝了xp光涂,用Fiddler去查看請求信息,后來就換了Firefox拧烦,最新版的Firefox沒有Firebug可用忘闻,但是自帶的開發(fā)者工具足夠用了。當(dāng)然Chrome我也沒卸載恋博,因為Chrome上有個很贊的功能齐佳,在元素界面查找元素的時候可以用css和xpath,可不是右鍵copy里面的css和xpath哦
臥了一個槽生音,忽略我上面說的吧,要寫博客了窒升,有一個請求Firefox竟然不給顯示了缀遍,還是虛擬機(jī)吧
后記
后記為什么要加載前言后面,而不是在文章最后饱须,我怕你不看瑟由。在這次分析中我基本沒有添加什么代碼,因為基本上每一個請求就是定義一個字典、一個url歹苦,然后發(fā)送請求青伤,獲取數(shù)據(jù),然后繼續(xù)下一個殴瘦。另一方面就是我并沒有做代碼優(yōu)化和整理狠角。我們都應(yīng)該知道對于沒有反爬措施的網(wǎng)站,基本上看兩個小時的爬蟲教程就能寫的出來蚪腋,對于有反爬的網(wǎng)站丰歌,最難得地方是分析階段,而不是發(fā)送請求屉凯。最后一點就是做這個也是一時興起立帖,積累一下經(jīng)驗,最主要是開始寫一寫博客悠砚。同時給像我一樣初學(xué)爬蟲的朋友一個例子晓勇、一個思路。
查票
車票預(yù)訂界面的url:https://kyfw.12306.cn/otn/leftTicket/init灌旧,選好票以后點擊查詢
多了一下兩個請求绑咱,第一個請求我沒用,沒有任何影響枢泰,我們就不用去管它描融,直接看第二個請求
https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-12-25&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT
看到了車次G101丽啡,8谋右、9是開車時間和到達(dá)時間硬猫,10是歷時补箍,商務(wù)座特等座9張余票,32行顯示9啸蜜,一等二等座都是有票坑雅,對應(yīng)30、31衬横,就不能具體確定了裹粤,暫時先不管,至少我們確定了這個請求是查詢出我們需要的車票信息了蜂林,那么再看一下請求參數(shù)遥诉,第一個是時間很容易理解拇泣,第四個好像是票的類型,成人票矮锈,翻譯一下單詞就知道了霉翔,反正每次都一樣,不用管了苞笨,中間兩個出發(fā)站债朵、目的地,不過這些字母是啥意思瀑凝,應(yīng)該是站名對應(yīng)的編碼序芦,在這個請求之前肯定是有對應(yīng)關(guān)系的,
https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9034
一個js的請求@bjb|北京北|VAP|beijingbei|bjb|0粤咪,拆分以后可以看到站名和編號
建議看完所有的分析在看代碼
def query_ticket_info(date, info):
js_info = json.loads(info)
if js_info.get("status") != True:
print("查詢余票失敗")
return
result = js_info.get("data").get("result")
for i in result:
lst = i.split('|')
if lst[11] != "Y": #主要是判斷是否開票了谚中,見下圖情況
continue
item = {
"預(yù)定號":lst[0], #預(yù)定號
"train_no":lst[2],
"車次":lst[3], #車次
"始發(fā)站":get_station_name_from_code(lst[4]), #始發(fā)站
"終點站":get_station_name_from_code(lst[5]), #終點站
"起始站":get_station_name_from_code(lst[6]), #起始站
"目標(biāo)站":get_station_name_from_code(lst[7]), #目標(biāo)站
"出發(fā)時間":"{} {}".format(date, lst[8]), #出發(fā)時間
"到達(dá)時間":get_end_time(date, lst[8], lst[9], lst[10]), #到達(dá)時間
"歷時":lst[10], #歷時
"train_location":lst[15],
"高級動臥":lst[21], #高級動臥
"軟臥":lst[23], #軟臥
"軟座":lst[24], #軟座
"特等座":lst[25], #特等座
"無座":lst[26], #無座
"硬臥":lst[28], #硬臥
"硬座":lst[29], #硬座
"二等座":lst[30], #二等座
"一等座":lst[31], #一等座
"商務(wù)座":lst[32], #商務(wù)座
"動臥":lst[33], #動臥
}
yield item
這個函數(shù)需要解釋一下,主要是這些站點信息是怎么找到的射窒,說一下思路
-
當(dāng)我們打開車票預(yù)訂界面的時候藏杖,是這樣的,下面是空的
-
點擊查詢后
- 由此我們知道車票信息是通過js動態(tài)添加的(maybe)脉顿,那么我們就查找動態(tài)創(chuàng)建出來的元素蝌麸,隨便在上面找一個元素特征,比如我找這個
-
通過分析js
然后把大部分我們需要的參數(shù)都對應(yīng)出來柑司,這樣就看到像我上面寫的函數(shù)那樣,取出我們需要的信息
-
其實有一種更簡單的方式锅劝,就是你查詢了余票信息以后攒驰,會看到余票幾張幾張,然后去對應(yīng)的信息參數(shù)中去找故爵,比如
我們就知道了32對應(yīng)的是商務(wù)座特等玻粪,多查詢一些站點就會把所有對應(yīng)索引都找出來
預(yù)訂
點擊預(yù)訂后看一下請求,記住我上一遍說過的,一般是看xhr和document請求劲室,
https://kyfw.12306.cn/otn/login/checkUser
重頭戲來了https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest
train_date:訂哪一天的票读虏,back_train_date:今天的時間责静,還有出發(fā)站和目的地。
已經(jīng)轉(zhuǎn)戰(zhàn)頭條了掘譬,不在這個平臺寫了泰演,TT號:Python集結(jié)號