python編程實(shí)現(xiàn)12306的一個(gè)小爬蟲(chóng)實(shí)例
本文思路主要來(lái)源于實(shí)驗(yàn)樓的教程,但是一些具體的一些細(xì)節(jié)是我自己發(fā)現(xiàn)的,比如哪里獲得站點(diǎn)對(duì)應(yīng)的3位英文編號(hào),怎么獲得這個(gè)查詢的url
本文用到的庫(kù)主要有requests(獲取url的內(nèi)容),prettytable(讓文本輸出美觀),argparse(命令行參數(shù)解析)
關(guān)于這些庫(kù)怎么使用,可以參見(jiàn)我之前的博文
1、首先打開(kāi)12306余票查詢的界面
https://kyfw.12306.cn/otn/lcxxcx/init
我們想要的信息當(dāng)然就是在輸入了始發(fā)站、終點(diǎn)站和日期之后各車次的時(shí)間和車票余量,那么我們嘗試在始發(fā)站使用檢查元素,觀察一下它是怎么上傳始發(fā)站的信息的,那么我們不妨隨便輸入出發(fā)地、目的地和信息,使用抓包工具來(lái)看看它是怎么發(fā)包的(使用瀏覽器也可以,因?yàn)槲覀冎恍枰榭窗膬?nèi)容,不需要更改包)
2、
在chrome的network中我們可以查看到我們點(diǎn)擊之后瀏覽器發(fā)送的所有包(關(guān)于http包的知識(shí)不熟悉的同學(xué),可以看看《圖解http》這本書(shū))
點(diǎn)擊查詢之后我們馬上就會(huì)注意到以query開(kāi)頭的這個(gè)包,顯然這就是一個(gè)查詢指令,我們看看這個(gè)包的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)過(guò)以上這些過(guò)程,我們大致就能知道我們需要做的是什么了,我們只需要更改url中的data,fromstaion,tostaion后面的內(nèi)容,然后用requests獲得response,然后解析這一串json字符就行了。
但是我們會(huì)發(fā)現(xiàn),日期還好說(shuō),對(duì)于fromstation和tostaion的代碼,我們?cè)撛趺崔k呢?
4、有兩種可能,一中可能是這些文件在服務(wù)器上,每回改變站點(diǎn)網(wǎng)頁(yè)都會(huì)從服務(wù)器請(qǐng)求這個(gè)站點(diǎn)的代碼,還有一種可能是這個(gè)已經(jīng)下載到本地了,如何判斷呢?我們不妨改變一下始發(fā)站,然后用抓包軟件(或者瀏覽器)觀察我們的瀏覽器是否向12306發(fā)送了包
把北京改成了上海,但是我們發(fā)現(xiàn)瀏覽器并沒(méi)有發(fā)送包
這樣我們基本可以肯定這個(gè)車站編號(hào)信息是存在本地了(已經(jīng)從服務(wù)器下載下來(lái))
5、我們這時(shí)候,就需要分析html來(lái)發(fā)現(xiàn)這個(gè)編號(hào)信息到底儲(chǔ)存在了那里
我們?cè)囍鴻z查一下出發(fā)地附近的html標(biāo)簽,在‘熱門'上面點(diǎn)擊檢查,我們很容易發(fā)現(xiàn)這個(gè)標(biāo)簽上面帶了一個(gè)onclick方法
我們發(fā)現(xiàn)這個(gè)onclick方法指向了一個(gè)js文件,并且名字是‘Stationfor12306',基本我們可以確定這個(gè)js文件就是我們需要的站點(diǎn)信息文件了。
6、我們嘗試在這個(gè)html(12306余票查詢界面)里面搜一下stationfor,我們馬上就能發(fā)現(xiàn),它就在<head>標(biāo)簽的<script>元素里,并且指向了一個(gè)url
進(jìn)入這個(gè)url看看,我們馬上就發(fā)現(xiàn)站點(diǎn)信息已經(jīng)被我們找到啦(注意這是一個(gè)相對(duì)URL,絕對(duì)url需要在前面補(bǔ)上https://kyfw.12306.cn/)
關(guān)于怎么獲取三位數(shù)的車站代碼,用正則,字符串查詢都是可以的啦,由于這里是固定的3位車站代碼,我就用簡(jiǎn)單的字符串查詢來(lái)提取這個(gè)代碼了。
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 = '車次 車站 到站時(shí)間 時(shí)長(zhǎng) 一等座 二等座 軟臥 硬臥 硬座 無(wú)座'.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 '這兩個(gè)站點(diǎn)沒(méi)有直達(dá)列車'
總結(jié)
以上就是本文關(guān)于python編程實(shí)現(xiàn)12306的一個(gè)小爬蟲(chóng)實(shí)例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
- 利用python代碼寫(xiě)的12306訂票代碼
- Python腳本實(shí)現(xiàn)12306火車票查詢系統(tǒng)
- Python模擬登錄12306的方法
- 使用Python神器對(duì)付12306變態(tài)驗(yàn)證碼
- 使用Python+Splinter自動(dòng)刷新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自動(dòng)查詢12306余票并發(fā)送郵箱提醒腳本
相關(guān)文章
Python實(shí)現(xiàn)微信自動(dòng)回復(fù)信息的功能(根據(jù)不同信息回復(fù)對(duì)應(yīng)的信息)
這篇文章主要介紹了Python實(shí)現(xiàn)微信自動(dòng)回復(fù)信息的功能(根據(jù)不同信息回復(fù)對(duì)應(yīng)的信息),我們使用的第三方包是UIAutomation,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09Tensorflow限制CPU個(gè)數(shù)實(shí)例
今天小編就為大家分享一篇Tensorflow限制CPU個(gè)數(shù)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02Python編程中的for循環(huán)語(yǔ)句學(xué)習(xí)教程
這篇文章主要介紹了Python編程中的for循環(huán)語(yǔ)句學(xué)習(xí)教程,是Python入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-10-10Python使用Pandas對(duì)csv文件進(jìn)行數(shù)據(jù)處理的方法
這篇文章主要介紹了Python使用Pandas對(duì)csv文件進(jìn)行數(shù)據(jù)處理的方法,本文通過(guò)實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5切換按鈕控件QPushButton詳細(xì)使用方法與實(shí)例
這篇文章主要介紹了python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5切換按鈕控件QPushButton詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下2020-02-02python3多重排序處理多數(shù)據(jù)的示例詳解
Python3的多重排序通常指的是對(duì)數(shù)據(jù)集合按照兩個(gè)或多個(gè)人數(shù)屬性進(jìn)行排序的過(guò)程,這可以通過(guò)將多個(gè)排序關(guān)鍵字作為元組傳遞給內(nèi)置的sorted()函數(shù)或者是使用列表推導(dǎo)式結(jié)合lambda函數(shù)完成,本文詳細(xì)分析了python3多重排序處理多數(shù)據(jù),需要的朋友可以參考下2024-07-07如何使用python爬取B站排行榜Top100的視頻數(shù)據(jù)
本文章向大家介紹python爬取b站排行榜,包括python爬取b站排行榜的具體代碼,對(duì)大家的學(xué)習(xí)或工作具有一定的參考價(jià)值,需要的朋友可以參考一下2021-09-09