用 Python 登入主流網站,我們的資料爬取少不了它
專案地址:https://github.com/CriseLYJ/awesome-python-login-model
作者收集了一些網站的登陸方式和爬蟲程式,有的通過 selenium 登入,有的則通過抓包直接模擬登入。作者希望該專案能幫助初學者學習各大網站的模擬登陸方式,並爬取一些需要的資料。
作者表示模擬登陸基本採用直接登入或者使用 selenium+webdriver 的方式,有的網站直接登入難度很大,比如 qq 空間和 bilibili 等,採用 selenium 登入相對輕鬆一些。雖然在登入的時候採用的是 selenium,但為了效率,我們也可以在登入後維護得到的 cookie。登入後,我們就能呼叫 requests 或者 scrapy 等工具進行資料採集,這樣資料採集的速度可以得到保證。
目前已經完成的網站有:
-
Facebook
-
無需身份驗證即可抓取 Twitter 前端 API
-
微博網頁版
-
知乎
-
QQZone
-
CSDN
-
淘寶
-
Baidu
-
果殼
-
JingDong 模擬登入和自動申請京東試用
-
163mail
-
拉鉤
-
Bilibili
-
豆瓣
-
Baidu2
-
獵聘網
-
微信網頁版登入並獲取好友列表
-
Github
-
爬取圖蟲相應的圖片
如下所示,如果我們滿足依賴項,那麼就可以直接執行程式碼,它會在圖蟲網站中下載搜尋到的影象。
如下所示為搜尋「秋天」,並完成下載的影象:
每一個網站都會有對應的登入程式碼,有的還有資料的爬取程式碼。以豆瓣為例,主要的登入函式如下所示,它會獲取驗證碼、處理驗證碼、返回登入資料完成登入,並最後保留 cookies。
def login(): captcha, captcha_id = get_captcha() # 增加表資料 datas['captcha-solution'] = captcha datas['captcha-id'] = captcha_id login_page = session.post(url, data=datas, headers=headers) page = login_page.text soup = BeautifulSoup(page, "html.parser") result = soup.findAll('div', attrs={'class': 'title'}) #進入豆瓣登陸後頁面,列印熱門內容 for item in result: print(item.find('a').get_text()) # 儲存 cookies 到檔案, # 下次可以使用 cookie 直接登入,不需要輸入賬號和密碼 session.cookies.save()
其中獲取並解決驗證碼的函式如下:
def get_captcha(): ''' 獲取驗證碼及其ID ''' r = requests.post(url, data=datas, headers=headers) page = r.text soup = BeautifulSoup(page, "html.parser") # 利用bs4獲得驗證碼圖片地址 img_src = soup.find('img', {'id': 'captcha_image'}).get('src') urlretrieve(img_src, 'captcha.jpg') try: im = Image.open('captcha.jpg') im.show() im.close() except: print('到本地目錄開啟captcha.jpg獲取驗證碼') finally: captcha = input('please input the captcha:') remove('captcha.jpg') captcha_id = soup.find( 'input', {'type': 'hidden', 'name': 'captcha-id'}).get('value') return captcha, captcha_id
當然這些都是簡單的演示,在 GitHub 專案中可以找到更多的示例。此外,作者表明由於網站策略或者樣式改變而導致程式碼失效,我們也可以提 Issue 或 Pull Requests。最後,該專案未來還會一直維護,很多東西哦也會慢慢改進,專案作者表明:
-
專案寫了一段時間後,發現程式碼風格、程式易用性、可擴充套件性、程式碼的可讀性,都存在一定的問題,所以接下來最重要的是重構程式碼,讓大家可以更容易的做出一些自己的小功能;
-
如果讀者覺得某個網站的登入很有代表性,可以在專案 issue 中提出;
-
網站的登入機制有可能經常的變動,所以當現在的模擬的登入的規則不能使用的時候,請專案在 issue 中提出。