python+Splinter實現(xiàn)12306搶票功能
本文實例為大家分享了python實現(xiàn)12306搶票功能的具體代碼,供大家參考,具體內(nèi)容如下
源碼記錄如下:
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
from splinter.browser import Browser
from time import sleep
import os
# from selenium.webdriver.chrome.options import Options
import logging
from log_class import Logger # 需要一個logger庫
import sys
reload(sys)
sys.setdefaultencoding('utf-8') # 防止由于Unicode編碼與ASCII編碼的不兼容造成錯誤
class BuyTicket(object):
def __init__(self, username, passwd, order, passengers, seatType, ticketType, daytime, starts, ends):
# 用戶名 密碼
self.username = username
self.passwd = passwd
# 車次,選擇第幾趟,0則從上之下依次點擊
self.order = order
# 乘客名
self.passengers = passengers
# 席位
self.seatType = seatType
self.ticketType = ticketType
# 時間格式2018-02-05
self.daytime = daytime
# 起始地和終點
self.starts = starts
self.ends = ends
self.login_url = 'https://kyfw.12306.cn/otn/login/init'
self.initMy_url = 'https://kyfw.12306.cn/otn/index/initMy12306'
self.ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init'
# 瀏覽器名稱
self.driver_name = 'firefox' # chrome firefox
# 火狐瀏覽器第三方驅(qū)動
self.executable_path = os.getcwd()+'/geckodriver' # 獲取工程目錄下的火狐驅(qū)動 chromedriver
def login(self):
# 訪問登錄網(wǎng)址
self.driver.visit(self.login_url)
# 填充用戶名
self.driver.fill("loginUserDTO.user_name", self.username)
# sleep(1)
# 填充密碼
self.driver.fill("userDTO.password", self.passwd)
logbticket.info("請手動輸入驗證碼...")
# print('請手動輸入驗證碼...') # 目前沒有自動驗證碼
# 循環(huán)等待登錄,登錄成功,跳出循環(huán)
while True:
if self.driver.url != self.initMy_url:
sleep(1)
else:
break
def start_buy(self):
# 這些設(shè)置都是必要的
# chrome_options = Options()
# chrome_options.add_argument("--no-sandbox")
# chrome_options.add_argument("--disable-setuid-sandbox")
# chrome_options.add_argument("disable-infobars") # 禁用網(wǎng)頁上部的提示欄
# self.driver = Browser(driver_name=self.driver_name, options=chrome_options, executable_path=self.executable_path)
self.driver = Browser(driver_name=self.driver_name,
executable_path=self.executable_path)
# 設(shè)置窗口大小尺寸
self.driver.driver.set_window_size(1400, 1000)
# 用戶登錄
self.login()
# 進入選票網(wǎng)站
self.driver.visit(self.ticket_url)
try:
logbticket.info("購票頁面開始....")
# print("購票頁面開始....")
# sleep(1)
# 加載查詢信息
self.driver.cookies.add({"_jc_save_fromStation": self.starts})
self.driver.cookies.add({"_jc_save_toStation": self.ends})
self.driver.cookies.add({"_jc_save_fromDate": self.daytime})
self.driver.reload()
count = 0
if self.order != 0:
while self.driver.url == self.ticket_url:
self.driver.find_by_text("查詢").click()
count = count+1
logbticket.info("第 %d 次點擊查詢..." % count)
# print("第 %d 次點擊查詢..." % count)
# sleep(1)
try:
self.driver.find_by_text("預(yù)訂")[self.order - 1].click() # 點擊第幾個“預(yù)訂”
sleep(1.5)
except Exception as e: # e是Exception 的一個instance
# print(e)
# print("預(yù)訂失敗...")
logbticket.error(e)
logbticket.error("預(yù)訂失敗...")
continue
else:
while self.driver.url == self.ticket_url:
self.driver.find_by_text("查詢").click()
count += 1
logbticket.info("第 %d 次點擊查詢..." % count)
# print("第 %d 次點擊查詢..." % count)
try:
for i in self.driver.find_by_text("預(yù)訂"):
i.click()
sleep(1)
except Exception as e:
# print(e)
# print("預(yù)訂失敗...")
logbticket.error(e)
logbticket.error("預(yù)訂失敗...")
continue
# print("開始預(yù)訂....")
logbticket.info("開始預(yù)訂....")
# sleep(1)
# self.driver.reload()
sleep(1)
# print("開始選擇用戶....")
logbticket.info("開始選擇用戶....")
for p in self.passengers:
pg = self.driver.find_by_text(p) # .last.click()
pg.last.click()
# print("提交訂單....")
logbticket.info("提交訂單....")
sleep(1)
i = 0
while len(self.passengers) > 0:
i = i + 1
seat_id_string = "seatType_" + str(i)
ticket_id_string = "ticketType_" + str(i)
self.driver.find_by_xpath('//select[@id="%s"]/option[@value="%s"]'
% (seat_id_string, self.seatType)).first._element.click()
self.driver.find_by_xpath('//select[@id="%s"]//option[@value="%s"]'
% (ticket_id_string, self.ticketType)).first._element.click()
# self.driver.select("confirmTicketType", "3")
self.passengers.pop()
sleep(1)
self.driver.find_by_id("submitOrder_id").click()
# print("開始選座...")
logbticket.info("開始選座...")
sleep(1.5)
# print("確認選座....")
logbticket.info("確認選座....")
self.driver.find_by_text("qr_submit_id").click()
except Exception as e:
# print(e)
logbticket.error(e)
city = {"深圳": "%u6DF1%u5733%2CSZQ",
"武漢": "%u6B66%u6C49%2CWHN",
"隨州": "%u968F%u5DDE%2CSZN"}
seatT = {"硬臥": "3",
"軟臥": "4",
"硬座": "1",
"二等座": "O",
"一等座": "M",
"商務(wù)座": "9"}
if __name__ == '__main__':
# 用戶名
username = "xxxxxxxx"
# 密碼
password = "xxxxxx"
# 車次選擇,0代表所有車次
order = 13
# 乘客名,比如passengers = ['丁小紅', '丁小明']
passengers = ["xxx", "xxx"]
# 日期,格式為:'2018-01-20'
daytime = "2018-04-05"
# 出發(fā)地(需填寫cookie值)
starts = city["xx"] # 武漢
# 目的地(需填寫cookie值)
ends = city["xx"] # 北京
# 席別
seatType = seatT["二等座"] # 二等座
# 票種
ticketType = "1" # 成人票
logbticket = Logger("bticket.log", logging.DEBUG, logging.ERROR)
BuyTicket(username, password, order, passengers, seatType, ticketType, daytime, starts, ends).start_buy()
火狐瀏覽器的驅(qū)動下載地址
logger庫文件:
源代碼如下:
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import logging
class Logger:
def __init__(self, path, clevel=logging.DEBUG, Flevel=logging.DEBUG):
self.logger = logging.getLogger(path)
self.logger.setLevel(logging.DEBUG)
fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
# 設(shè)置CMD日志
sh = logging.StreamHandler()
sh.setFormatter(fmt)
sh.setLevel(clevel)
# 設(shè)置文件日志
fh = logging.FileHandler(path)
fh.setFormatter(fmt)
fh.setLevel(Flevel)
self.logger.addHandler(sh)
self.logger.addHandler(fh)
def debug(self, message):
self.logger.debug(message)
def info(self, message):
self.logger.info(message)
def war(self, message):
self.logger.warn(message)
def error(self, message):
self.logger.error(message)
def cri(self, message):
self.logger.critical(message)
if __name__ == '__main__':
logyyx = Logger('yyx.log', logging.ERROR, logging.DEBUG)
logyyx.debug('一個debug信息')
logyyx.info('一個info信息')
logyyx.war('一個warning信息')
logyyx.error('一個error信息')
logyyx.cri('一個致命critical信息')
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于python SMTP實現(xiàn)自動發(fā)送郵件教程解析
這篇文章主要介紹了基于python實現(xiàn)自動發(fā)送郵件教程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06
數(shù)據(jù)清洗--DataFrame中的空值處理方法
今天小編就為大家分享一篇數(shù)據(jù)清洗--DataFrame中的空值處理方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
Python實現(xiàn)圖像尺寸和格式轉(zhuǎn)換處理的示例詳解
這篇文章主要為大家詳細介紹了如何利用Python實現(xiàn)圖像尺寸獲取和格式轉(zhuǎn)換處理的功能,文中的示例代碼講解詳細,感興趣的可以了解一下2023-04-04
Pycharm遠程連接服務(wù)器跑代碼的實現(xiàn)
本文主要介紹了Pycharm遠程連接服務(wù)器跑代碼的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Pytorch DataLoader 變長數(shù)據(jù)處理方式
今天小編就為大家分享一篇Pytorch DataLoader 變長數(shù)據(jù)處理方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
Python + Chrome抓取AJAX動態(tài)數(shù)據(jù)的兩種方法
在現(xiàn)代 Web 開發(fā)中,AJAX技術(shù)被廣泛應(yīng)用于動態(tài)加載數(shù)據(jù),使得網(wǎng)頁能夠在不刷新的情況下更新內(nèi)容,本文將詳細介紹 Python + Chrome 如何抓取 AJAX 動態(tài)數(shù)據(jù),并提供兩種方法的完整實現(xiàn)代碼,需要的朋友可以參考下2025-04-04

