此文轉自:https://zhuanlan.zhihu.com/p/28587931 轉錄只是爲了方便學習,感謝他的分享php
Python模擬登錄讓很多人傷透腦筋,今天奉上一種萬能登錄方法。你無須精通HTML,甚至也無須精通Python,但卻能讓你成功的進行模擬登錄。本文講的是登錄全部網站的一種方法,並不侷限於微博與知乎,僅用其做爲例子來說解。html
用到的庫有「selenium」和「requests」。經過selenium進行模擬登錄,而後將Cookies傳入requests,最終用requests進行網站的抓取。優勢就是不但規避了「selenium」其自己抓取速度慢的問題(由於僅僅用其做爲登錄),又規避了利用requests登錄時須要製做繁瑣的Cookies的過程(由於是從selenium直接拿來cookies)。文章前面列出了步驟與代碼,後面補充了登錄微博與知乎的實例。python
文章最後給出了一個懶人的方法。想要走捷徑的朋友直接看第四部知乎登錄。該方法適用於登錄全部網站,僅用知乎做爲實例以方便講解。web
------------開始---------chrome
須要材料:1.本身喜歡的webdriver (必須) 2.Anaconda(可選)。selenium是藉助瀏覽器而運行的,所以須要額外下載一款小型瀏覽器。Anaconda推薦你們也去下載一個,它裏面包含了衆多python的庫,用起來很方便,並且免費!友情連接:1.谷歌 Web Driver下載 2. Anaconda下載api
導入selenium庫瀏覽器
from selenium import webdriver
明確模擬瀏覽器在電腦中存放的位置,好比我存在了D盤cookie
chromePath = r'D:\Python Program\chromedriver.exe'
用selenium的webdriver方程指明瀏覽器的路徑,同時打開一個瀏覽器。模擬瀏覽器有多種可選,好比Firefox, Safari。本次用的是谷歌的模擬瀏覽器。注意:'.Chome'是大寫字母。函數
wd = webdriver.Chrome(executable_path= chromePath)
讓webdriver爲你填寫用戶名和密碼學習
wd.find_element_by_xpath('用戶名選項卡位置').send_keys('用戶名') wd.find_element_by_xpath('密碼選項卡位置').send_keys('密碼')
讓webdrive點擊登錄,如果按鈕就選擇用click(),如果表單就選擇submit()。
wd.find_element_by_xpath('登錄按鈕所在位置').click() #如果按鈕
wd.find_element_by_xpath('登錄按鈕所在位置').submit() #如果表單
登錄完成,全部的cookies如今都存在了'wd'裏面,可隨時調用。
導入requests庫,並構建Session()
import reqeusts
req = requests.Session()
從‘wd'裏調出cookies
cookies = wd.get_cookies()
將selenium形式的cookies轉換爲requests可用的cookies。
for cookie in cookies:
req.cookies.set(cookie['name'],cookie['value'])
大功告成!嘗試用requests來抓取網頁。
req.get('待測試的連接')
以上就是python模擬登錄的萬能方法,你無需分析傳遞給網站的Cookies。只須要告訴python在什麼地方填寫用戶名與密碼就能夠。十分的便利。
import requests from selenium import webdriver chromePath = r'瀏覽器存放位置' wd = webdriver.Chrome(executable_path= chromePath) #構建瀏覽器 loginUrl = 'http://www.weibo.com/login.php' wd.get(loginUrl) #進入登錄界面 wd.find_element_by_xpath('//*[@id="loginname"]').send_keys('userword') #輸入用戶名 wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[2]/div/input').send_keys('password') #輸入密碼 wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[6]/a').click() #點擊登錄 req = requests.Session() #構建Session cookies = wd.get_cookies() #導出cookie for cookie in cookies: req.cookies.set(cookie['name'],cookie['value']) #轉換cookies test = req.get('待測試的連接')
解釋下關鍵的幾個步驟:
1.找位置。推薦使用谷歌瀏覽器來查找每一個元素的Xpath,參看這個:從Chrome獲取XPATH路徑。
2. 選擇click函數仍是submit函數。推薦每一個都試一下,總會有一個成功的。
3.登錄微博是被要求輸入驗證碼怎麼辦?有時登錄微博會被要求輸入驗證碼,這個時候咱們能夠加一行手動輸入驗證碼的代碼。例如:
wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[6]/a').click() #點擊登錄
wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[3]/div/input').send_keys(input("輸入驗證碼: "))
wd.find_element_by_xpath('//*[@id="pl_login_form"]/div/div[3]/div[6]/a').click()#再次點擊登錄
輸入驗證碼的時候須要點擊兩次登錄。由於驗證碼的輸入框只有在點擊了一次登錄後纔會彈出來!根據每一個網站的不一樣而靈活應用selenium是十分重要的!但這個和分析那些Cookies比起來簡直是過小兒科了。
知乎常常更新,所以即便方法寫好了也可能很差用。所以我想到了一個終極方法,半手動登錄。僅用selenium打開一個瀏覽器,而後手動輸入帳號密碼,有驗證碼就填驗證碼。等到成功登錄以後使用「get_cookies()」函數來調出它的Cookies。這個方法雖然看起來笨了點,可是效率比那些幾百行的代碼不知道要高多少!並且你還能夠用手機掃描二維碼登錄!只要這些登錄操做是在selenium所打開的瀏覽器內進行,selenium就能夠徹底記錄下這些Cookies。代碼以下:
import time
import requests
from selenium import webdriver
chromePath = r'瀏覽器儲存的位置'
wd = webdriver.Chrome(executable_path= chromePath)
time.sleep(45)#設定45秒睡眠,期間進行手動登錄。十分關鍵,下面有解釋。
cookies = wd.get_cookies()#調出Cookies
req = requests.Session()
for cookie in cookies:
req.cookies.set(cookie['name'],cookie['value'])
req.headers.clear()
test = req.get('待測試的連接')
req.headers.clear() 是刪除原始req裏面標記有python機器人的信息。這個信息會被一些網站(好比知乎)捕捉到。形成登錄爬取失敗。務必要刪除!
time.sleep()能夠暫停執行下面的程序。在此期間你能夠進行手動登錄,掃描二維碼等。而後在45秒事後再讓python執行後面的「cookies = wd.get_cookies()」。selenium的get.cookies方程能夠抓取到你進行手動登錄事後的cookies。時間值的設定根據本身須要的時間。若是你在程序中已經將網站名、用戶名、密碼、等所有輸入就剩下一個驗證碼須要手動的話,僅設定幾秒鐘就能夠了!加入time.sleep的好處就是程序自己是不須要中止執行的!下面的全部程序能夠無縫銜接。
感謝你們讀到這,文章最初說的懶人方法就是我登錄知乎用到的這種方法,半手動。可是也不要以爲它很差,畢竟咱們的目的是爬取網站的內容,儘快解決登錄問題。開始爬取工做纔是正確的方向。這個方法能夠幫您迅速登錄網站,節省大量時間。這個方法萬能的原理就是它調用了真實的瀏覽器。那麼只要在正常狀況下瀏覽器可以訪問的網站就均可以用這個方法登錄。
-------------------------------------------
問題1:若是網站禁用selenium怎麼辦?
解決方案:這種狀況極少。網站若是採用這種反爬蟲手段的話很容易誤傷真正的用戶。若是真的遇到這種狀況,只須要隱藏掉selenium中顯示你是機器人的信息就能夠了。參考連接:Can a website detect when you are using selenium with chromedriver?
問題2:如何讓新打開的webdriver帶有曾經保存過的cookies?
解決方案:將獲取的cookies保存在本地。下次登錄的時候直接導入本地的cookies。參考連接:How to save and load cookies using python selenium webdriver
from selenium import webdriver from requests import Session from time import sleep req = Session() req.headers.clear() chromePath = r'D:\Python Program\chromedriver.exe' wd = webdriver.Chrome(executable_path= chromePath) zhihuLogInUrl = 'https://www.zhihu.com/signin' wd.get(zhihuLogInUrl) wd.find_element_by_xpath('/html/body/div[1]/div/div[2]/div[2]/div[1]/div[1]/div[2]/span').click() wd.find_element_by_xpath('/html/body/div[1]/div/div[2]/div[2]/form/div[1]/div[1]/input').send_keys('username') wd.find_element_by_xpath('/html/body/div[1]/div/div[2]/div[2]/form/div[1]/div[2]/input').send_keys('password') sleep(10) #手動輸入驗證碼 wd.find_element_by_xpath('/html/body/div[1]/div/div[2]/div[2]/form/div[2]/button').submit() sleep(10)#等待Cookies加載 cookies = wd.get_cookies() for cookie in cookies: req.cookies.set(cookie['name'],cookie['value'])