很久沒寫東西了,最近學習了一下模擬登陸,以校園網爲例,做一記錄。python
去年的時候寫過一篇模擬登陸的文章,用的是登陸後的cookies,這種操做比較傻瓜,也不智能,不夠自動化,本質仍是手動登陸。
此次我嘗試把登陸過程用python進行,預先提供帳號、密碼便可。web
衆所周知(本校兄弟姐妹),本校全部身份認證現已徹底由jaccount進行,只要經過了這一層驗證,就至關於登陸成功了。
瀏覽器
mail....edu.cn
剛開始想用requests
解決全部問題,直到試了許屢次也未能成功解決登陸跳轉的問題,只好放棄,轉用更簡單的selenium。selenium是一款可見便可得的自動化測試工具,在爬蟲上用起來十分方便,它經過模擬人實際的操做實現對瀏覽器的控制,好比輸入、點擊、拖動等事件。cookie
依次按照上述流程,進行編碼(完整代碼見文末):dom
browser.get('https://mail.sjtu.edu.cn')
此時,會彈出瀏覽器,自動打開該網頁,固然,也會自動跳轉到jaccount驗證頁面。工具
帳號、密碼都比較好搞定,本身預設好就好了。而後經過開發者工具定位文本框位置,由如下命令能夠輸入到相應的文本框內。
學習
input_user = browser.find_element_by_id('user') input_user.send_keys(user) input_pass = browser.find_element_by_id('pass') input_pass.send_keys(pswd)
麻煩的仍是驗證碼。首先要找到驗證碼圖片源,再經過OCR工具進行識別。
經過分析,發現驗證碼是由https://jaccount.sjtu.edu.cn/jaccount/captcha
這個站點生成的。要獲取到正確的驗證碼,須要傳入相應的uuid參數,以及cookies。OCR工具目前比較好用的是tesseract,所幸咱們這個驗證碼比較簡單,識別率很高。測試
經過對源碼進行搜索,終於找到uuid了,就在這個登陸表單裏,經過xpath獲取一下,拿到value
ui
uuid = browser.find_element_by_xpath('//form/input[@name="uuid"]') params = { 'uuid': uuid.get_attribute('value') }
此處爲了便捷,我使用requests進行驗證碼下載,而selenium的cookies也和requests不一樣,selenium是比較完整的信息,以下:編碼
[{'domain': 'mail.sjtu.edu.cn', 'httpOnly': True, 'name': 'JSESSIONID', 'path': '/', 'secure': False, 'value': '12l9qesot3vw61sz8brl8i74ir'}, {'domain': 'mail.sjtu.edu.cn', 'httpOnly': True, 'name': 'ZM_AUTH_TOKEN', 'path': '/', 'secure': False, 'value': '0_7b1bfd5665cabda2816d04d7e4f8438022c54538_69643d33363a35373935373238652d346539362d346434372d383837332d6331666264356130343337643b6578703d31333a313536393836323130303632323b747970653d363a7a696d6272613b753d313a613b7469643d31303a323134323231343838363b76657273696f6e3d31333a382e382e395f47415f333031393b'}, {'domain': '.sjtu.edu.cn', 'expiry': 1569818955, 'httpOnly': False, 'name': '_gat', 'path': '/', 'secure': False, 'value': '1'}, {'domain': '.sjtu.edu.cn', 'expiry': 1569905295, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': 'GA1.3.452166840.1569818896'}, {'domain': '.sjtu.edu.cn', 'expiry': 1632890895, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA1.3.1066557857.1569818896'}]
而咱們傳入requests的只須要cookie名字和值便可,故可經過字典推導式,生成requests所需的cookies:
cookies = browser.get_cookies() cookies = {i["name"]: i["value"] for i in cookies}
這樣一來就能夠獲取驗證碼了,
response = requests.get(captcha_url, cookies=cookies, params=params) with open('img.jpeg', 'wb+') as f: f.writelines(response)
這樣驗證碼就被保存到img.jpeg
文件中,識別驗證碼只須要如下兩行代碼便可:
image = Image.open('img.jpeg') code = pytesseract.image_to_string(image)
最後,輸入驗證碼,並肯定,就能夠跳轉回登陸後的郵箱界面。
input_code = browser.find_element_by_id('captcha') input_code.send_keys(code) input_code.send_keys(Keys.ENTER)
若是你用的是可視化瀏覽器,這時候就能夠看到本身的郵箱了。
能夠再看看當前的url,是否是已經跳轉回郵箱的url了呢?
print(browser.current_url)
成功登陸以後,要爬取什麼東西都很簡單了,好比課程表、好大學在線的課件等等~
from selenium import webdriver from selenium.webdriver.common.keys import Keys import requests import pytesseract from PIL import Image browser = webdriver.Chrome() url = "https://mail.sjtu.edu.cn/" captcha_url = "https://jaccount.sjtu.edu.cn/jaccount/captcha" user = 'ben' pswd = '********' def get_captcha(captcha_url, cookies, params): response = requests.get(captcha_url, cookies=cookies, params=params) with open('img.jpeg', 'wb+') as f: f.writelines(response) try: browser.get(url) cookies = browser.get_cookies() cookies = {i["name"]: i["value"] for i in cookies} uuid = browser.find_element_by_xpath('//form/input[@name="uuid"]') params = { 'uuid': uuid.get_attribute('value') } get_captcha(captcha_url, cookies, params) image = Image.open('img.jpeg') code = pytesseract.image_to_string(image) print(code) input_user = browser.find_element_by_id('user') input_user.send_keys(user) input_pass = browser.find_element_by_id('pass') input_pass.send_keys(pswd) input_code = browser.find_element_by_id('captcha') input_code.send_keys(code) input_code.send_keys(Keys.ENTER) print(browser.current_url) finally: print('success!')