1. 程式人生 > 實用技巧 >(九)selenium實現12306模擬登入

(九)selenium實現12306模擬登入

登陸的唯一困難在於驗證碼的識別,此處使用第三方平臺超級鷹進行驗證碼識別。

from selenium import webdriver
import time
from PIL import Image
from selenium.webdriver import ActionChains
import requests
from hashlib import md5

from selenium.webdriver import Chrome
from selenium.webdriver import ChromeOptions

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() # 檢測規避 option = ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) driver = Chrome(options=option) bro = webdriver.Chrome(executable_path='./chromedriver.exe') # 最大化螢幕 bro.maximize_window() # 傳送請求 bro.get('https://kyfw.12306.cn/otn/resources/login.html') # 找到賬號的登陸的標籤 btn = bro.find_elements_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a')[0] btn.click() time.sleep(2) # 將當前頁面截圖生成圖片 bro.save_screenshot('12306.png') # 定位到要擷取的圖片 pic = bro.find_element_by_xpath('/html/body/div[2]/div[2]/div[1]/div[2]/div[3]/div/div[4]/img') # 得到當前圖片的左上角座標 location = pic.location # 得到圖片的長和寬 size = pic.size # 得到圖片左上角和右下角的座標 截圖準確度與電腦縮放佈局有關 當前為125% rangle = (location['x'] * 1.25, location['y'] * 1.25, (location['x'] + size['width']) * 1.25, (location['y'] + size['height']) * 1.25) # 儲存生成的驗證碼圖片 i = Image.open('./12306.png') code_img_name = 'code.png' # 裁剪檔案的檔名稱 frame = i.crop(rangle) # 根據指定區域進行裁剪 frame.save(code_img_name) # 利用超級鷹識別驗證碼 chaojiying = Chaojiying_Client('Mrterrific', 'WQ2017617sxy', ' 905993') im = open('./code.png', 'rb').read() result = chaojiying.PostPic(im, 9004)['pic_str'] all_list = [] if '|' in result: # 多個結果 print(result) ret_list = result.split('|') # 148,102|236,203 for ret in ret_list: # 將一組座標放入列表 x_y = [] x = ret.split(',')[0] y = ret.split(',')[0] x_y.append(x) x_y.append(y) all_list.append(x_y) else: x_y = [] x = result.split(',')[0] y = result.split(',')[0] x_y.append(x) x_y.append(y) all_list.append(x_y) for ret in all_list: x = int(ret[0]) y = int(ret[1]) ActionChains(bro).move_to_element_with_offset(pic, x, y).click().perform() # 以圖片物件為參考系 將滑鼠移動到相對圖片x,y處 點選圖片 time.sleep(0.5) bro.find_element_by_id('J-userName').send_keys('xxxx') bro.find_element_by_id('J-password').send_keys('ssss') bro.find_element_by_id('J-login').click() time.sleep(3) bro.quit()