python編程實(shí)現(xiàn)12306的一個小爬蟲實(shí)例
本文思路主要來源于實(shí)驗(yàn)樓的教程,但是一些具體的一些細(xì)節(jié)是我自己發(fā)現(xiàn)的,比如哪里獲得站點(diǎn)對應(yīng)的3位英文編號,怎么獲得這個查詢的url
本文用到的庫主要有requests(獲取url的內(nèi)容),prettytable(讓文本輸出美觀),argparse(命令行參數(shù)解析)
關(guān)于這些庫怎么使用,可以參見我之前的博文
1、首先打開12306余票查詢的界面
https://kyfw.12306.cn/otn/lcxxcx/init
我們想要的信息當(dāng)然就是在輸入了始發(fā)站、終點(diǎn)站和日期之后各車次的時間和車票余量,那么我們嘗試在始發(fā)站使用檢查元素,觀察一下它是怎么上傳始發(fā)站的信息的,那么我們不妨隨便輸入出發(fā)地、目的地和信息,使用抓包工具來看看它是怎么發(fā)包的(使用瀏覽器也可以,因?yàn)槲覀冎恍枰榭窗膬?nèi)容,不需要更改包)
2、

在chrome的network中我們可以查看到我們點(diǎn)擊之后瀏覽器發(fā)送的所有包(關(guān)于http包的知識不熟悉的同學(xué),可以看看《圖解http》這本書)

點(diǎn)擊查詢之后我們馬上就會注意到以query開頭的這個包,顯然這就是一個查詢指令,我們看看這個包的url
'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2016-10-04&from_station=BJP&to_station=XKS'
然后我們看看它的response

仔細(xì)觀察就能發(fā)現(xiàn)它其實(shí)是一串json格式的字符串(要非常有經(jīng)驗(yàn)。。。。)
3、經(jīng)過以上這些過程,我們大致就能知道我們需要做的是什么了,我們只需要更改url中的data,fromstaion,tostaion后面的內(nèi)容,然后用requests獲得response,然后解析這一串json字符就行了。
但是我們會發(fā)現(xiàn),日期還好說,對于fromstation和tostaion的代碼,我們該怎么辦呢?
4、有兩種可能,一中可能是這些文件在服務(wù)器上,每回改變站點(diǎn)網(wǎng)頁都會從服務(wù)器請求這個站點(diǎn)的代碼,還有一種可能是這個已經(jīng)下載到本地了,如何判斷呢?我們不妨改變一下始發(fā)站,然后用抓包軟件(或者瀏覽器)觀察我們的瀏覽器是否向12306發(fā)送了包

把北京改成了上海,但是我們發(fā)現(xiàn)瀏覽器并沒有發(fā)送包
這樣我們基本可以肯定這個車站編號信息是存在本地了(已經(jīng)從服務(wù)器下載下來)
5、我們這時候,就需要分析html來發(fā)現(xiàn)這個編號信息到底儲存在了那里
我們試著檢查一下出發(fā)地附近的html標(biāo)簽,在‘熱門'上面點(diǎn)擊檢查,我們很容易發(fā)現(xiàn)這個標(biāo)簽上面帶了一個onclick方法

我們發(fā)現(xiàn)這個onclick方法指向了一個js文件,并且名字是‘Stationfor12306',基本我們可以確定這個js文件就是我們需要的站點(diǎn)信息文件了。
6、我們嘗試在這個html(12306余票查詢界面)里面搜一下stationfor,我們馬上就能發(fā)現(xiàn),它就在<head>標(biāo)簽的<script>元素里,并且指向了一個url

進(jìn)入這個url看看,我們馬上就發(fā)現(xiàn)站點(diǎn)信息已經(jīng)被我們找到啦(注意這是一個相對URL,絕對url需要在前面補(bǔ)上https://kyfw.12306.cn/)

關(guān)于怎么獲取三位數(shù)的車站代碼,用正則,字符串查詢都是可以的啦,由于這里是固定的3位車站代碼,我就用簡單的字符串查詢來提取這個代碼了。
7、剩下的工作,基本就是代碼實(shí)現(xiàn)了,關(guān)于具體怎么實(shí)現(xiàn),我把我的代碼貼在下面了。
#coding=utf-8
import requests
import argparse
import datetime
import re
from prettytable import PrettyTable
now = datetime.datetime.now()
tomorrow = now+datetime.timedelta(days=1)
tomorrow = tomorrow.strftime('%Y-%m-%d')
print tomorrow
argument = argparse.ArgumentParser()
argument.add_argument('--fromcity','-f',default='hangzhoudong')
argument.add_argument('--tocity','-t',default='xiamen')
argument.add_argument('--date','-d',default=tomorrow)
# argument.add_argument('-d',action='store_true')
args =argument.parse_args()
from_station = args.fromcity
to_station = args.tocity
Date = args.date
stationlist_url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js'
r = requests.get(stationlist_url, verify=False)
stationlist = r.content
ToStation = ''
FromStation = ''
placea = stationlist.find(from_station)
placeb = stationlist.find(to_station)
for i in range(-4,-1):
FromStation += stationlist[placea+i]
for i in range(-4,-1):
ToStation += stationlist[placeb+i]
query_url='https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate='+Date+'&from_station='+FromStation+'&to_station='+ToStation
r = requests.get(query_url,verify=False)
with open('json.txt','w') as fp:
fp.write(str(r.json()))
if 'datas' in r.json()["data"]:
rj = r.json()["data"]["datas"]
pt = PrettyTable()
header = '車次 車站 到站時間 時長 一等座 二等座 軟臥 硬臥 硬座 無座'.split()
pt._set_field_names(header)
for x in rj:
ptrow = []
ptrow.append(x["station_train_code"])
ptrow.append('\n'.join([x["from_station_name"],x["to_station_name"]]))
ptrow.append('\n'.join([x["start_time"], x["arrive_time"]]))
ptrow.append(x["lishi"].replace(':','h')+'m')
ptrow.append(x['zy_num'])
ptrow.append(x['ze_num'])
ptrow.append(x['rw_num'])
ptrow.append(x['yw_num'])
ptrow.append(x['yz_num'])
ptrow.append(x['wz_num'])
pt.add_row(ptrow)
print pt
else :
print '這兩個站點(diǎn)沒有直達(dá)列車'
總結(jié)
以上就是本文關(guān)于python編程實(shí)現(xiàn)12306的一個小爬蟲實(shí)例的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
- 利用python代碼寫的12306訂票代碼
- Python腳本實(shí)現(xiàn)12306火車票查詢系統(tǒng)
- Python模擬登錄12306的方法
- 使用Python神器對付12306變態(tài)驗(yàn)證碼
- 使用Python+Splinter自動刷新12306火車票
- Python實(shí)現(xiàn)破解12306圖片驗(yàn)證碼的方法分析
- python實(shí)現(xiàn)12306火車票查詢器
- Python使用面向?qū)ο蠓绞絼?chuàng)建線程實(shí)現(xiàn)12306售票系統(tǒng)
- python+pyqt實(shí)現(xiàn)12306圖片驗(yàn)證效果
- python自動查詢12306余票并發(fā)送郵箱提醒腳本
相關(guān)文章
ubuntu系統(tǒng)下多個python版本如何設(shè)置默認(rèn)python和pip
pip是一個用來安裝Python軟件包的工具,下面這篇文章主要給大家介紹了關(guān)于ubuntu系統(tǒng)下多個python版本如何設(shè)置默認(rèn)python和pip的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
Python中的 ansible 動態(tài)Inventory 腳本
這篇文章主要介紹了Python中的 ansible 動態(tài)Inventory 腳本,本章節(jié)通過實(shí)例代碼從mysql數(shù)據(jù)作為數(shù)據(jù)源生成動態(tài)ansible主機(jī)為入口介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2020-01-01
Python把對應(yīng)格式的csv文件轉(zhuǎn)換成字典類型存儲腳本的方法
今天小編就為大家分享一篇Python把對應(yīng)格式的csv文件轉(zhuǎn)換成字典類型存儲腳本的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-02-02
python實(shí)現(xiàn)將中文日期轉(zhuǎn)換為數(shù)字日期
這篇文章主要介紹了python實(shí)現(xiàn)將中文日期轉(zhuǎn)換為數(shù)字日期,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
Python解析json時提示“string indices must be integers”問題解決方法
這篇文章主要介紹了Python解析json時提示“string indices must be integers”問題解決方法,結(jié)合實(shí)例形式分析了Python解析json字符串操作規(guī)范與相關(guān)使用技巧,需要的朋友可以參考下2019-07-07
django 實(shí)現(xiàn)celery動態(tài)設(shè)置周期任務(wù)執(zhí)行時間
今天小編就為大家分享一篇django 實(shí)現(xiàn)celery動態(tài)設(shè)置周期任務(wù)執(zhí)行時間,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
人工智能學(xué)習(xí)Pytorch數(shù)據(jù)集分割及動量示例詳解
這篇文章主要為大家介紹了人工智能學(xué)習(xí)Pytorch數(shù)據(jù)集分割及動量示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11
Python自動修改電腦靜態(tài)IP地址的實(shí)現(xiàn)示例
通過Python自動修改電腦的靜態(tài)IP地址可以極大地提高我們的工作效率,減少手動修改IP地址帶來的錯誤,本文就來介紹一下Python自動修改電腦靜態(tài)IP地址的實(shí)現(xiàn)示例,感興趣的可以了解一下2023-11-11

