python解決12306登錄驗證碼的實現
在傢無聊,線代和高數看不懂,整點事情幹,就準備預定回學校的高鐵票,於是就有瞭這個文章
準備工作
1.pip安裝chromediver,當然也可以手動解壓(網上的教程好像沒有提到pip,手動安裝到C盤pycharm裡面的Scripts就行瞭)
chromedriver.storage.googleapis.com/index.html這是chromedriver文件官網,在chrome裡面設置查看自己的版本,然後找對應的版本就完瞭
2.註冊個超級鷹,http://www.chaojiying.com/contact.html,挺厲害的打碼平臺,微信公眾號綁定一下賬號給1000積分,足夠幹12306驗證碼瞭
開始實戰講解
1.選擇chrome打開12306然後切換到賬號登錄
默認是掃碼登錄
F12然後點擊賬號登錄
3.復制xPath,/html/body/div[2]/div[2]/ul/li[2]/a
代碼實現
from selenium.webdriver import Chrome web = Chrome() web.get('https://kyfw.12306.cn/otn/resources/login.html') time.sleep(3) web.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
2.下載驗證碼(截屏也可以)然後發送給超級鷹
超級鷹官網有個官方文檔,下載然後pychram打開,其實就很簡單,然後把賬號密碼改成你自己的,
from chaojiying import Chaojiying_Client
驗證碼需要時間加載,所以要sleep(3)就夠瞭,
3.拿到坐標然後模擬點擊
好像這個官方叫什麼偏移量,挺高大上的,說白瞭就是建立一個坐標系,給個x,y然後點擊就完瞭,默認左上方是原點
for pre_location in location_list: #切割出來x,y坐標 location = pre_location.split(',') x = int(location[0]) y = int(location[1]) ActionChains(web).move_to_element_with_offset(img,x,y).click().perform()
4.登錄以後有個滑動驗證
現在我還沒有找到方法控制滑動速度,勻速運動,但是12306並沒有因為這個驗證失敗
ActionChains(web).drag_and_drop_by_offset(button,340,0).perform()
button是那個滑塊的Xpath,我記得好像是長度330,340肯定是夠用瞭,那個0就是豎y的方向上的滑動
12306靠webdriver判斷是不是爬蟲
剛開始12306圖片和滑動驗證通過以後一直說驗證失敗,百思不得其解,百度發現是因為這個
這是正常頁面下的,也就是我改瞭以後的,加一個這個代碼,欺騙一下
def trick_not_chromedriver(): option = Options() option.add_argument('--disable-blink-features=AutomationControlled') return option
這個要調用在前面,靠後一點就不行瞭
全部代碼
from selenium.webdriver import Chrome import requests,time from hashlib import md5 from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.chrome.options import Options class Chaojiying_Client(object): def __init__(self, username, password, soft_id): self.username = username password = password.encode('utf8') self.password = md5(password).hexdigest() self.soft_id = soft_id self.base_params = { 'user': self.username, 'pass2': self.password, 'softid': self.soft_id, } self.headers = { 'Connection': 'Keep-Alive', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', } def PostPic(self, im, codetype): """ im: 圖片字節 codetype: 題目類型 參考 http://www.chaojiying.com/price.html """ params = { 'codetype': codetype, } params.update(self.base_params) files = {'userfile': ('ccc.jpg', im)} r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers) return r.json() def ReportError(self, im_id): """ im_id:報錯題目的圖片ID """ params = { 'id': im_id, } params.update(self.base_params) r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers) return r.json() #獲取驗證碼 def get_verify_img(web): web.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click() time.sleep(5) verify_img = web.find_element_by_xpath('//*[@id="J-loginImg"]') return verify_img #識別驗證碼返回坐標 def discern_verify_img(verify_img): chaojiying = Chaojiying_Client('超級鷹賬號', '密碼', '軟件ID') responce = chaojiying.PostPic(verify_img.screenshot_as_png, 9004) pre_location = responce['pic_str'] location_list = pre_location.split("|") # 把split寫錯瞭,卡瞭半天 # type_pre_location = type(pre_location) return location_list # return type_pre_location #拿到坐標模擬點擊 def click_and_enter(web,location_list,img): for pre_location in location_list: #切割出來x,y坐標 location = pre_location.split(',') x = int(location[0]) y = int(location[1]) ActionChains(web).move_to_element_with_offset(img,x,y).click().perform() def enter(web): # input() web.find_element_by_xpath('//*[@id="J-userName"]').send_keys('賬號') web.find_element_by_xpath('//*[@id="J-password"]').send_keys('密碼') web.find_element_by_xpath('//*[@id="J-login"]').click() #滑動驗證 def move_verify(web): button = web.find_element_by_xpath('//*[@id="nc_1__scale_text"]/span') ActionChains(web).drag_and_drop_by_offset(button,340,0).perform() # 騙12306這不是chromedriver def trick_not_chromedriver(): option = Options() option.add_argument('--disable-blink-features=AutomationControlled') return option #現在有一個疫情防控的確認按鈕,點一下這個 def yqfk(web): web.get('https://kyfw.12306.cn/otn/leftTicket/init') time.sleep(1) web.find_element_by_xpath('//*[@id="qd_closeDefaultWarningWindowDialog_id"]').click() #進入查詢界面,思路正則表達式,不可信 def get_stick_text(web): web.get('https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2021-04-16&leftTicketDTO.from_station=TNV&leftTicketDTO.to_station=CZF&purpose_codes=0X00') response = web.find_element_by_xpath('/html/body/pre').text return (response) #父子節點一個一個找,顯示餘票 if __name__ == '__main__': web = Chrome(options=trick_not_chromedriver()) web.get('https://kyfw.12306.cn/otn/resources/login.html') time.sleep(5) # click_and_enter(discern_verify_img(get_verify_img())) img = get_verify_img(web) click_and_enter(web,discern_verify_img(img),img) time.sleep(5) enter(web) time.sleep(5) move_verify(web) time.sleep(1) yqfk(web) time.sleep(2) get_verify_img(web)
已經可以登錄的,結果就是這個界面
還有一個想法是餘票檢測,在搞瞭,應該快瞭
到此這篇關於python解決12306登錄驗證碼的實現的文章就介紹到這瞭,更多相關python 12306登錄驗證碼 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- None Found