基於python3爬蟲的對12306餘票查詢的圖形介面
阿新 • • 發佈:2018-12-09
學了爬蟲也有將近四個月了,寫過的爬蟲也有蠻多的。最近剛要開學,學生來校大多坐火車來,就尋思做一個餘票查詢的小工具,順帶溫習一下所學的爬蟲知識還有對python程式設計的一些用法,將從12306網上爬取到達實時資料做成圖形介面,以下便是我的小工具的version1的具體做法,工具中稍有些bug未能改正,但是我想先把我自己所獲得的東西先放到我的部落格上面來,有想法的小夥伴可以聯絡我,歡迎大路大神指教! import requests from tkinter import Tk,Label,Entry,Button,Text,END 首先引入咱們工具所需要用到的庫以及類,其中requests庫是用來想網路發起請求的一個模組,該模組在python3的網路爬蟲中比較常用,然後就是GUI程式設計中所需的tkinter模組,從其中引入給各類用來生成圖形介面。 接下來就是爬取我們所需要的資訊和資料了。我們過通過對12306網站的分析,從開發者工具中找到所需要請求的內容和提交的引數如下圖所示: https://img-blog.csdn.net/20180914210504299?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM0OTk0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 https://img-blog.csdn.net/20180914210520486?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM0OTk0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 通過對網頁的分析可以得到我們需要用get請求的方法並增加引數params來獲取網頁的響應,在提交引數的時候我們需要搞清楚每個變數代表的含義,所以之後我們將會再一次爬取,另外一個網頁得到每個城市的英文程式碼。獲取到的響應內容為json格式的字串,我們通過對字典取值的方法和便利找到我們所需要的資訊。具體請看爬取程式碼: 1.爬取我們所需資料的主要邏輯程式碼,將內容追加到列表中,然後返回; def ticket_check(self,date,from_station,to_station): url = 'https://kyfw.12306.cn/otn/leftTicket/queryA?' data = { 'leftTicketDTO.train_date':date, 'leftTicketDTO.from_station':from_station, 'leftTicketDTO.to_station':to_station, 'purpose_codes':'ADULT' } res = requests.get(url,params = data) res.encoding = res.apparent_encoding info = res.json()['data']['result'] a = self.box for i in info: train = i.split('|')[3] start_time = i.split('|')[8] end_time = i.split('|')[9] total_time = i.split('|')[10] a.append('\n'+'\t'+'車次:'+train+ '\t\t' + '出發時間:' +start_time+ '\t\t'\ +'到達時間:' +end_time+ '\t\t'+ '用時:'+ total_time+'\n'+'\n') return a 該類方法中傳入三個引數,分別為時間、出發地、目的地,通過對網頁的爬取和解析,將資訊儲存再列表中並返回; 2.獲取出發地和目的地的城市英文程式碼; def get_tstation_name(self,t): url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9061' res = requests.get(url) res.encoding = res.apparent_encoding ret = res.text ret = ret[20:-2] ret_list = ret.split('|') station_name = ret_list[1::5] station_code = ret_list[2::5] name_code = dict(tuple(zip(station_name, station_code))) if t in name_code.keys(): return name_code[t] else: return name_code[input('請重新輸入正確的到達地:')] 傳入目的地的中文,對網頁獲取和解析,得到所需要的城市英文程式碼並返回;同理,獲得出發地的英文程式碼並返回; 3.接下來就是圖形介面的編寫了,主要圖形如下圖所示: ![這裡寫圖片描述](https://img-blog.csdn.net/20180914211727520?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM0OTk0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) 通過輸入出發時間、出發地、目的地,點選‘查詢’按鈕,對餘票資訊的列印,將結果顯示在下方的Text框中,以下為圖形介面的主要邏輯程式碼: def __init__(self): #main window self.window = Tk() self.window.title('Train check tool') self.window.geometry('600x750+400+20') #label self.label1 = Label(self.window,text = '請輸入出發日期:') self.label1.place(x=60,y = 10) self.label2 = Label(self.window,text = '請輸入出發地:') self.label2.place(x=60,y = 40) self.label3 = Label(self.window,text = '請輸入目的地:') self.label3.place(x=60,y = 70) self.label4 = Label(self.window,text = '查詢結果如下:') self.label4.place(x=60,y=150) #entry self.enter1 = Entry(self.window) self.enter1.place(x = 200,y=10) self.enter2 = Entry(self.window) self.enter2.place(x = 200,y=40) self.enter3 = Entry(self.window) self.enter3.place(x = 200,y=70) # button check self.button1 = Button(self.window, text='查詢', command=self.check) self.button1.place(x=100, y=110, width=100) # button cls self.button2 = Button(self.window, text='清空', command=self.clear) self.button2.place(x=270, y=110, width=100) # text field self.text = Text(self.window) self.text.place(x=10, y=170, height=540) self.box = [] 設定好介面的大小和距離後,通過Button中的command引數將事件驅動連線起來,達到點選按鈕完成事件,其中clear方法稍簡單些,只要通過在定義的entry、text物件中的delete方法將所有內容清空即可,程式碼如下: def clear(self): self.enter1.delete(0,END) self.enter2.delete(0, END) self.enter3.delete(0, END) self.text.delete('1.0',END) 主要的功能實現的介面就是check方法了,通過對輸入框的get方法,將輸入的內容獲取到後,分別定義三個變數來接收,之後再呼叫我們之前寫好的對12306網站爬蟲的方法,我們前面說過,將所需資訊內容儲存在列表中,目的是將列表的內容在Text中用insert方法進行插入,實現對內容的抓取和展現。以下為check方法的具體邏輯程式碼: def check(self): date = self.enter1.get() f = self.enter2.get() t = self.enter3.get() f_des = self.get_fstation_name(f) t_des = self.get_tstation_name(t) content = self.ticket_check(date,f_des,t_des) self.text.insert(END,content) 主要功能實現以及全部寫好了,接下來我們將所有的程式碼整合起來,稍加整理,定義一個Application類,將所有的邏輯程式碼整合在該類中,然後我們例項化該類,呼叫類方法run將整個程式執行起來,其中run方法為: def run(self): self.window.mainloop() 例項化該類,執行程式: if __name__ =='__main__': app = Application() app.run() 至此,火車票餘票查詢小工具就做好了,其中還有很多值得改正的地方,我也繼續學習,不斷完善不斷改進。以下為程式執行結果: https://img-blog.csdn.net/20180914213329802?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM0OTk0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70 總結一下以上所寫的全部內容,這是我的第一步部落格文章,在部落格編寫期間,總是感覺自己在程式碼編寫和部落格文章時的不平衡,我的想法可能比較奇怪,今後一定多多完善,歡迎大家留言討論和指正,謝謝! 來自一個正在打怪升級的軟院大學生