有了之前的基礎(chǔ)理論箫爷,就可以付諸實(shí)踐啦
典型案例是央行征信報(bào)告系統(tǒng)的官網(wǎng),年初在登陸頁(yè)面加入了安全控件
并且只可以通過(guò)IE瀏覽器登陸
其中的密碼輸入框就是安全性更高的控件輸入旱捧,由于我的瀏覽器已經(jīng)安裝過(guò)控件了耘子,所以在密碼輸入未知顯示的是控件框,仔細(xì)對(duì)比登陸名的dom框她我,還是可以看出區(qū)別的
1. 準(zhǔn)備
需要一臺(tái)windwos電腦虹曙,帶IE瀏覽器,進(jìn)入央行征信登陸頁(yè)面:
https://ipcrs.pbccrc.org.cn/
安裝好輸入框控件
python環(huán)境的話番舆,安裝selenium包酝碳,配好iedriver,這里的操作網(wǎng)上教程一大堆恨狈,略過(guò)
2. 登陸分析
抓包分析疏哗,可以找到登陸入口
輸入登陸名、輸入密碼禾怠、驗(yàn)證碼沃斤,點(diǎn)擊登陸按鈕即可登陸:
這里先異步調(diào)用打碼平臺(tái)打碼
然后selenium輸入登陸名圣蝎,winIO輸入密碼,等待打碼完成輸入驗(yàn)證碼最后提交
3. 實(shí)踐
我們創(chuàng)建一個(gè)模擬登陸類衡瓶,將整套登陸操作封裝一起來(lái)
初始化部分:
def __init__(self):
self.driver = webdriver.Ie()
self.coo = {}
self.captch = ''
self.event = Event()
driver變量用表示瀏覽器實(shí)例
coo變量:登陸成功的cookie
captch:驗(yàn)證碼
基礎(chǔ)設(shè)施:
驗(yàn)證碼用打碼平臺(tái)的徘公,控件輸入密碼使用之前準(zhǔn)備好的winIO輸入
其中打平臺(tái)的打碼時(shí)間不太穩(wěn)定,我們采用線程異步的方式打碼
from threading import Thread, Event
簡(jiǎn)單介紹下Event,這個(gè)對(duì)象是一個(gè)線程安全的事件信號(hào)哮针,調(diào)用打碼平臺(tái)的時(shí)候先調(diào)用Event.set()方法关面,在其他線程同步完成系列操作之后可以調(diào)用Event.wait(time)方法,等待time時(shí)間十厢,這里給打碼平臺(tái)設(shè)置5s等待時(shí)間等太,超時(shí)打碼未完成則認(rèn)作打碼失敗,更多進(jìn)程線程介紹點(diǎn)這里:http://kaito-kidd.com/2018/05/11/python-advance-process-thread/
def async_ocr(self):
t = Thread(target=self.ocr)
t.setDaemon(True)
t.start()
def ocr(self):
#調(diào)用打碼方法
rst = TesFunc2(self.img)
self.captch = rst
self.event.set()
winIO的包裝:
之前介紹了winIO:http://www.reibang.com/p/40a9de88153f
把輸入密碼的api進(jìn)一步封裝到類中:
def passwd(self, pwd):
for i in pwd:
input_key(i)
time.sleep(0.1)
主體登陸邏輯
1.請(qǐng)求登陸接口:
def start(self):
self.driver.get('https://ipcrs.pbccrc.org.cn/page/login/loginreg.jsp')
img = 'pictures/{}.png'.format(time.time())
self.driver.save_screenshot(img)
element = self.driver.find_element_by_xpath('//img[@class="yzm_img"]')
left = element.location['x']
top = element.location['y']
right = element.location['x'] + element.size['width']
bottom = element.location['y'] + element.size['height']
im = Image.open(img)
im = im.crop((left + 23, top + 1, right, bottom))
im.save(img)
self.img = img
# self.hand = self.driver.current_window_handle
self.captch = ''
該方法的作用是請(qǐng)求登陸頁(yè)面蛮放,截取驗(yàn)證碼保存為bytes類型缩抡,后面調(diào)用打碼平臺(tái),打碼
截屏用的selenium的diver對(duì)象的方法包颁,摳圖需要用到pillow庫(kù)瞻想,導(dǎo)入:
from PIL import Image
其中的im.crop方法四個(gè)參數(shù)是驗(yàn)證碼的像素點(diǎn),瀏覽器可能略有誤差娩嚼,調(diào)整了一下左側(cè)向右偏移了20多像素
2.輸入登陸信息:
def form_submit_control(self, username, pwd):
# 異步打碼
self.async_ocr()
time.sleep(0.1)
self.passwd(pwd)
name = self.driver.find_element_by_xpath('//input[@id="loginname"]')
name.send_keys(username)
img = self.driver.find_element_by_xpath('//input[@id="_@IMGRC@_"]')
# 等待打碼時(shí)間通知
try:
self.event.wait(5)
except:
pass
if not self.captch:
return '打碼平臺(tái)異常'
img.send_keys(self.captch)
submit = self.driver.find_element_by_xpath('//input[@type="submit"]')
submit.click()
""""此處處理登陸后續(xù)操作..."""
整體的登陸邏輯就完成了