基于Python實(shí)現(xiàn)火車票搶票軟件
導(dǎo)語(yǔ)
每年的節(jié)假日一到,大家頭疼的總時(shí)同一個(gè)問(wèn)題:你買到回家的票了嗎?
尤其是大型的節(jié)日:”比如國(guó)慶、春節(jié)......“
數(shù)以億計(jì)的人口遷移,讓車票成了一年里最難買到的那張票。
跨站買票、買短途票上車補(bǔ)票、準(zhǔn)點(diǎn)撿漏等已是老生常談的技巧。隨著互聯(lián)網(wǎng)的發(fā)展,搶票軟件成為購(gòu)票熱門渠道。搶票軟件的到底靠譜嘛?能搶到票嘛?
近日,小編給大家就正式編寫一款Python實(shí)現(xiàn)查票以及自動(dòng)購(gòu)票搶票的小程序給大家,希望大家如愿!
環(huán)境準(zhǔn)備
1)運(yùn)行環(huán)境:Python 3 、Pycharm、谷歌瀏覽器、谷歌驅(qū)動(dòng) 。
2)模塊準(zhǔn)備:
requests ---> pip install requests (數(shù)據(jù)請(qǐng)求模塊)
prettytable ---> pip install prettytable (打印好看一些 )
selenium ---> pip install selenium==3.141.0 (模擬人的行為去操作瀏覽器)
json ---> 內(nèi)置模塊 不需要安裝
PS小編有話說(shuō):(新手看過(guò)來(lái))
模塊安裝問(wèn)題:
如果安裝python第三方模塊:
1. win + R 輸入 cmd 點(diǎn)擊確定, 輸入安裝命令 pip install 模塊名 (pip install requests) 回車
2. 在pycharm中點(diǎn)擊Terminal(終端) 輸入安裝命令
安裝失敗原因:
失敗一: pip 不是內(nèi)部命令
解決方法: 設(shè)置環(huán)境變量
失敗二: 出現(xiàn)大量報(bào)紅 (read time out)
解決方法: 因?yàn)槭蔷W(wǎng)絡(luò)鏈接超時(shí), 需要切換鏡像源
- 清華:https://pypi.tuna.tsinghua.edu.cn/simple
- 阿里云:https://mirrors.aliyun.com/pypi/simple/
- 中國(guó)科技大學(xué) https://pypi.mirrors.ustc.edu.cn/simple/
- 華中理工大學(xué):https://pypi.hustunique.com/
- 山東理工大學(xué):https://pypi.sdutlinux.org/
- 豆瓣:https://pypi.douban.com/simple/
例如:pip3 install -i https://pypi.doubanio.com/simple/ 模塊名
失敗三: cmd里面顯示已經(jīng)安裝過(guò)了, 或者安裝成功了, 但是在pycharm里面還是無(wú)法導(dǎo)入
解決方法: 可能安裝了多個(gè)python版本 (anaconda 或者 python 安裝一個(gè)即可) 卸載一個(gè)就好
或者你pycharm里面python解釋器沒(méi)有設(shè)置好。
如何配置pycharm里面的python解釋器?
1. 選擇file(文件) >>> setting(設(shè)置) >>> Project(項(xiàng)目) >>> python interpreter(python解釋器)
2. 點(diǎn)擊齒輪, 選擇add
3. 添加python安裝路徑
pycharm如何安裝插件?
1. 選擇file(文件) >>> setting(設(shè)置) >>> Plugins(插件)
2. 點(diǎn)擊 Marketplace 輸入想要安裝的插件名字 比如:翻譯插件 輸入 translation / 漢化插件 輸入 Chinese
3. 選擇相應(yīng)的插件點(diǎn)擊 install(安裝) 即可
4. 安裝成功之后 是會(huì)彈出 重啟pycharm的選項(xiàng) 點(diǎn)擊確定, 重啟即可生效
項(xiàng)目思路
12306 每天只能退票三次
查票
購(gòu)票
建議谷歌或者火狐....
爬蟲采集數(shù)據(jù)思路:
一. 分析數(shù)據(jù)來(lái)源
車票信息, 來(lái)源那個(gè)數(shù)據(jù)包 <車票信息請(qǐng)求那個(gè)網(wǎng)站url地址可以得到>
開(kāi)發(fā)者工具 1 2
二. 代碼實(shí)現(xiàn)步驟:
1. 發(fā)送請(qǐng)求, 對(duì)于剛剛分析得到url地址發(fā)送請(qǐng)求
https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2022-07-02&leftTicketDTO.from_station=CSQ&leftTicketDTO.to_station=SHH&purpose_codes=ADULT
2. 獲取數(shù)據(jù), 獲取服務(wù)器返回響應(yīng)數(shù)據(jù), response
3. 解析數(shù)據(jù), 提取我們想要車次信息
代碼展示
import requests # 導(dǎo)入漂亮的表格輸出模塊 ---> 第三方模塊 需要 在cmd里面進(jìn)行 pip install prettytable import prettytable as pt # 導(dǎo)入json import json # 導(dǎo)入selenium模塊 ---> 第三方模塊 需要 在cmd里面進(jìn)行 pip install selenium==3.141.0 from selenium import webdriver # 導(dǎo)入賬號(hào)密碼 from password import account, Password # 導(dǎo)入selenium控制鍵盤 from selenium.webdriver.common.keys import Keys # 創(chuàng)建瀏覽器 <打開(kāi)瀏覽器> 瀏覽器驅(qū)動(dòng)放在python安裝目錄里面就不需要添加路徑 def get_ticket(num, from_station, to_station, date_key): driver = webdriver.Chrome() # 輸入網(wǎng)址 driver.get('https://kyfw.12306.cn/otn/resources/login.html') # 通過(guò)元素定位, 找到賬號(hào)輸入框 輸入賬號(hào) send_keys() 發(fā)送或者輸入內(nèi)容 driver.find_element_by_css_selector('#J-userName').send_keys(account) # 通過(guò) css 選擇器查找元素 # 通過(guò)元素定位, 找到密碼輸入框 輸入密碼 send_keys() 發(fā)送或者輸入內(nèi)容 driver.find_element_by_css_selector('#J-password').send_keys(Password) # 通過(guò) css 選擇器查找元素 # 通過(guò)元素定位, 找到登陸按鈕, 點(diǎn)擊登陸 driver.find_element_by_css_selector('#J-login').click() # 隱式等待 driver.implicitly_wait(10) # 通過(guò)元素定位, 點(diǎn)擊彈窗確定按鈕 .表示class # 表示ID driver.find_element_by_css_selector('.modal-ft .btn').click() # 通過(guò)元素定位, 點(diǎn)擊車票預(yù)定 driver.find_element_by_css_selector('#link_for_ticket').click() # 通過(guò)元素定位, 點(diǎn)擊鍵盤回車 driver.find_element_by_css_selector('#fromStationText').send_keys(Keys.ENTER) # 通過(guò)元素定位, 清空輸入框內(nèi)容 driver.find_element_by_css_selector('#fromStationText').clear() # 通過(guò)元素定位, 點(diǎn)擊一下輸入框 driver.find_element_by_css_selector('#fromStationText').click() # 通過(guò)元素定位, 輸入出發(fā)城市 driver.find_element_by_css_selector('#fromStationText').send_keys(from_station) # 通過(guò)元素定位, 點(diǎn)擊鍵盤回車 driver.find_element_by_css_selector('#fromStationText').send_keys(Keys.ENTER) driver.find_element_by_css_selector('#toStationText').clear() driver.find_element_by_css_selector('#toStationText').click() driver.find_element_by_css_selector('#toStationText').send_keys(to_station) driver.find_element_by_css_selector('#toStationText').send_keys(Keys.ENTER) date = driver.find_element_by_css_selector('.inp-w #train_date') date.clear() date.send_keys(date_key) # 通過(guò)元素定位, 點(diǎn)擊查詢按鈕 driver.find_element_by_css_selector('#query_ticket').click() if num == 1: driver.find_element_by_css_selector(f'#queryLeftTable tr:nth-child({num}) a.btn72').click() elif num != 1: driver.find_element_by_css_selector(f'#queryLeftTable tr:nth-child({num + 1}) a.btn72').click() # #normalPassenger_0 driver.find_element_by_css_selector('#normalPassenger_1').click() driver.find_element_by_css_selector('#submitOrder_id').click() driver.find_element_by_css_selector('#qr_submit_id').click() driver.find_element_by_css_selector('#qr_submit_id').click() f = open('city.json', encoding='utf-8') text = f.read() # 讀取文件 json_data = json.loads(text) from_city = input('請(qǐng)輸入你要出發(fā)城市: ') to_city = input('請(qǐng)輸入你要到達(dá)城市: ') date = input('請(qǐng)輸入你要出發(fā)的時(shí)間: ') from_station = json_data[from_city] to_station = json_data[to_city] """ 發(fā)送請(qǐng)求, 模擬瀏覽器對(duì)于url地址發(fā)送請(qǐng)求 快捷批量替換方法: 選中內(nèi)容, ctrl + R 輸入正則表達(dá)式命令點(diǎn)擊全部替換即可 (.*?): (.*) '$1': '$2', """ # 確定請(qǐng)求網(wǎng)址 ---> 如果對(duì)于長(zhǎng)鏈接, 我們是可以分段寫 ? 后面都是屬于請(qǐng)求參數(shù) url = 'https://kyfw.12306.cn/otn/leftTicket/query' # 請(qǐng)求參數(shù) ---> 字典數(shù)據(jù)類型, 構(gòu)建成完整鍵值對(duì), 鍵值對(duì)與鍵值對(duì)之間要用逗號(hào)隔開(kāi) data = { 'leftTicketDTO.train_date': date, 'leftTicketDTO.from_station': from_station, 'leftTicketDTO.to_station': to_station, 'purpose_codes': 'ADULT', } # 請(qǐng)求頭 ---> 偽裝模擬瀏覽器的, 把python代碼偽裝成瀏覽器發(fā)送請(qǐng)求 headers = { # User-Agent: 用戶代理, 表示瀏覽器基本身份標(biāo)識(shí) 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36', } # 發(fā)送請(qǐng)求 ---> 返回?cái)?shù)據(jù) <Response [200]> 響應(yīng)對(duì)象 200狀態(tài)碼表示請(qǐng)求成功 response = requests.get(url=url, params=data, headers=headers) # 獲取數(shù)據(jù) response.json() 獲取響應(yīng)對(duì)象json字典數(shù)據(jù) # 解析數(shù)據(jù) ---> 根據(jù)數(shù)據(jù)類型以及你想要獲取數(shù)據(jù)內(nèi)容, 選擇最合適提取方式 根據(jù)冒號(hào)左邊的內(nèi)容, 提取冒號(hào)右邊內(nèi)容 result = response.json()['data']['result'] # 實(shí)例化對(duì)象 tb = pt.PrettyTable() tb.field_names = [ '序號(hào)', '車次', '出發(fā)時(shí)間', '到達(dá)時(shí)間', '耗時(shí)', '特等座', '一等', '二等', '軟臥', '硬臥', '硬座', '無(wú)座', ] page = 0 lis = [] # for循環(huán) 就把列表里面元素一個(gè)一個(gè)提取出來(lái) for index in result: # split() 字符串分割方法 --> 返回是列表 content_list = index.split('|') # 根據(jù)列表索引位置提取內(nèi)容 num = content_list[3] # 車次 start_time = content_list[8] # 出發(fā)時(shí)間 end_time = content_list[9] # 到達(dá)時(shí)間 use_time = content_list[10] # 耗時(shí) topGrade = content_list[25] # 特等座 if topGrade: pass else: topGrade = content_list[32] first_class = content_list[31] # 一等 second_class = content_list[30] # 二等 hard_sleeper = content_list[28] # 硬臥 hard_seat = content_list[29] # 硬座 no_seat = content_list[26] # 無(wú)座 soft_sleeper = content_list[23] # 軟臥 dit = { '車次': num, '出發(fā)時(shí)間': start_time, '到達(dá)時(shí)間': end_time, '耗時(shí)': use_time, '特等座': topGrade, '一等': first_class, '二等': second_class, '軟臥': soft_sleeper, '硬臥': hard_sleeper, '硬座': hard_seat, '無(wú)座': no_seat, } lis.append(dit) tb.add_row([ page, num, start_time, end_time, use_time, topGrade, first_class, second_class, soft_sleeper, hard_sleeper, hard_seat, no_seat, ]) page += 1 # 更加方便直觀查看 索引位置 ---> 列表可以通過(guò)索引位置取值 # num = 0 # for i in content_list: # # i 列表里面元素, num 對(duì)應(yīng)列表索引位置 # print(i, num) # num += 1 # break print(tb) num = input('請(qǐng)輸入你想要購(gòu)買車票序號(hào): ') get_ticket(num=int(num), from_station=from_city, to_station=to_city, date_key=date)
到此這篇關(guān)于基于Python實(shí)現(xiàn)火車票搶票軟件的文章就介紹到這了,更多相關(guān)Python火車票搶票內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 教你用Python來(lái)制作一個(gè)自動(dòng)搶票的腳本小程序
- 一款開(kāi)源的Python一鍵搶票神器詳細(xì)配置
- python爬蟲實(shí)現(xiàn)最新12306搶票
- Python自動(dòng)化xpath實(shí)現(xiàn)自動(dòng)搶票搶貨
- Python爬蟲 12306搶票開(kāi)源代碼過(guò)程詳解
- python并發(fā)編程多進(jìn)程 模擬搶票實(shí)現(xiàn)過(guò)程
- Python實(shí)現(xiàn)12306火車票搶票系統(tǒng)
- python+splinter自動(dòng)刷新?lián)屍惫δ?/a>
- python+Splinter實(shí)現(xiàn)12306搶票功能
- 一百多行python代碼實(shí)現(xiàn)搶票助手
- Python編寫一個(gè)多線程的12306搶票程序的示例
相關(guān)文章
淺談function(函數(shù))中的動(dòng)態(tài)參數(shù)
下面小編就為大家?guī)?lái)一篇淺談function(函數(shù))中的動(dòng)態(tài)參數(shù)。小編覺(jué)得聽(tīng)不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04Python+tkinter實(shí)現(xiàn)高清圖片保存
作為愛(ài)玩電腦的你是不是也需要經(jīng)常更換一下自己的電腦壁紙呢?但是在網(wǎng)上有很多心儀的圖片想要保存下來(lái),如果一張張的去保存那效率又低。所以本文用Python寫一個(gè)保存圖片的功能,把我們的圖片給保存到我們的電腦,需要的可以參考一下2022-03-03python中sort()和sorted()的區(qū)別及用法實(shí)例
我們通常會(huì)遇到對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行排序的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于python中sort()和sorted()的區(qū)別及用法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06Python常見(jiàn)格式化字符串方法小結(jié)【百分號(hào)與format方法】
這篇文章主要介紹了Python常見(jiàn)格式化字符串方法,結(jié)合實(shí)例形式分析了百分號(hào)方法和format函數(shù)進(jìn)行字符串格式化的具體使用技巧,需要的朋友可以參考下2016-09-09python實(shí)現(xiàn)while循環(huán)打印星星的四種形狀
今天小編就為大家分享一篇python實(shí)現(xiàn)while循環(huán)打印星星的四種形狀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11使用Python實(shí)現(xiàn)查找PDF中的指定文本并高亮顯示
在處理大量PDF文檔時(shí),有時(shí)我們需要快速找到特定的文本信息,本文將提供三個(gè)Python示例來(lái)幫助你在PDF文件中快速查找并高亮指定的文本,希望對(duì)大家有所幫助2024-03-03