參考精通Python網絡爬蟲實戰php
首先,針對chinaunixhtml
import urllib.request #原書做者提供的測試url url="http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LctlC" headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5193.400 QQBrowser/10.0.1066.400") postdata=urllib.parse.urlencode({ "username":"xiaojieshisilang", "password":"XXXXX" }).encode('utf-8') req=urllib.request.Request(url,postdata) req.add_header(headers[0],headers[1]) data=urllib.request.urlopen(req).read() #print (data) fhandle=open("./8.html","wb") fhandle.write(data) fhandle.close() #設置要爬去的該網站下其餘網頁的網址 url2="http://bbs.chinaunix.net/forum.php?mod=guide&view=my"#這是從網頁登陸之後,才能進入的我的空間。 req2=urllib.request.Request(url2,postdata) req2.add_header(headers[0],headers[1]) data2=urllib.request.urlopen(req2).read() #print (data2) fhandle=open("./8_2.html","wb") fhandle.write(data2) fhandle.close()
上面的password須要你本身去註冊。node
關鍵點在於獲取用於針對post用戶名和密碼信息以後的那個URL,以及構建PostData表單字典。python
F12打開調試界面。git
輸入錯誤的用戶名add和密碼add,能夠看到URL信息以下:github
以及FormData信息以下:web
同時,咱們就能構造出chrome
postdata=urllib.parse.urlencode({ "username":"xiaojieshisilang", "password":"XXXXXXXXXXX" }).encode('utf-8')
這裏要填入正確的用戶名和密碼。瀏覽器
最後代碼的運行結果是:打開8_html服務器
同時,8-2.html則是:
關於構建postData時的名稱,除了用F12調試的方式。
另一種是,直接放在文本框,用右鍵檢查的方式,從而定位到相應的源碼,取出表單的名稱,好比:username和password。
輸入錯誤的用戶名和密碼
這個時候,查看Form Data,即表單數據。
import urllib.request url="https://passport.csdn.net/account/verify" headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5193.400 QQBrowser/10.0.1066.400") postdata=urllib.parse.urlencode({ "username":"183247166@qq.com", "password":"XXXXXX" }).encode('utf-8') req=urllib.request.Request(url,postdata) req.add_header(headers[0],headers[1]) data=urllib.request.urlopen(req).read() #print (data) fhandle=open("./8.html","wb") fhandle.write(data) fhandle.close() #設置要爬去的該網站下其餘網頁的網址 url2="https://download.csdn.net/my"#這是從網頁登陸之後,才能進入的我的空間。 req2=urllib.request.Request(url2,postdata) req2.add_header(headers[0],headers[1]) data2=urllib.request.urlopen(req2).read() #print (data2) fhandle=open("./8_2.html","wb") fhandle.write(data2) fhandle.close()
結果是:
不能正確登陸csdn,而且爬蟲。
這說明,csdn的驗證機制,不是簡單的一個post就能完成的。
https://blog.csdn.net/yanggd1987/article/details/52127436
這個連接是前人的博客。你們同時能夠參考Python3網絡爬蟲開發實戰一書中的觀點,要先獲取隱藏表單中的值,而後再構造post數據,用python模擬登陸。
可是,最新版本,截止到當前時間2018年7月13日09:54:03時,csdn的驗證機制變了。具體以下:
以前的:
values = { "username":"用戶名", "password":"密碼", "lt":lt, "execution":execution, "_eventId":"submit"
}
如今的:
刷新csdn的登陸界面,能夠看到開發者模式記錄的第一個請求實Get請求,訪問的是https://passport.csdn.net/account/login,相似於github的機制,這個時候,訪問這個頁面,會忘隱藏表單中填入相關的數據。具體請求的信息以下:
服務器會Response一些set_cookie的信息,要求瀏覽器客戶端設置cookie文件。
這些暫時不用考慮。
咱們點擊「掃碼登陸」,而後鼠標放在密碼的文本框上,右鍵選擇檢查,能夠看到:
FORM中隱藏表單中的lt,execution等都已經填入了相關值。你能夠進一步作實驗,每次刷新login頁面,這些值都會變化。咱們發現fkid這個新屬性(csdn最新添加的屬性)並無值。還是value。咱們參考Python3網絡爬蟲開發實戰中的方法編寫以下代碼取出隱藏表單的值:
這裏面用到XPATH。
如何知道XPATH,直接在F12模式的表單input位置,右鍵選擇copy XPATH便可。
import urllib.request import requests from lxml import etree #獲取加載的it/execution/fkid等的值 headers = { 'Referer': 'https://www.csdn.net/', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5193.400 QQBrowser/10.0.1066.400', 'Host': 'passport.csdn.net' } login_url="https://passport.csdn.net/account/login" session = requests.Session() response = session.get(login_url, headers=headers) selector=etree.HTML(response.text) execution=selector.xpath('//input[@name="execution"]/@value')[0] print (execution) _eventId=selector.xpath('//input[@name="_eventId"]/@value')[0] print (_eventId) lt=selector.xpath('//input[@name="lt"]/@value')[0] print (lt) fkid=selector.xpath('//*[@id="fkid"]/@value')[0] print (fkid)
能夠看到,fkid的值根本不存在。這個時候,咱們就要思考post數據中明明發出了fkid值,爲何這裏不存在。(由於運行js代碼更新的表單數據是不能經過在網頁中抓取的。)
咱們查看網頁預加載的幾個js文件,找到以下js代碼:
https://csdnimg.cn/release/passport/history/js/apps/login.js?v=1.3.9
它裏面有:
也即初始化的時候,就爲登陸按鈕註冊了一個onclick函數,執行的內容是,檢查用戶名,檢查密碼,而後計算fkid的值。
咱們下斷點,而後在瀏覽器中隨便輸入abd做爲用戶名,隨便輸入abd做爲密碼。
而後跟蹤到81行代碼處。
到達斷點位置之後,在console控制檯取出真正的fkid值。
SMSdk是csdn開發者加入到window屬性中的。
將鼠標放在SMSdk上,會顯示其中的getDeviceId方法,
鼠標放在getDeviceId上,右鍵show function definition
能夠看到代碼被混淆了,目的的就是防止被別人看。
用python寫一個功能徹底相同的代碼不太現實。若是知道機制,還能夠用python從網頁中取出某些元素,而後算出fkid,傳回服務器,同用戶名、密碼一塊兒造成驗證。可是如今不知道機制,就連計算的js代碼都被混淆了。
因而:第一,輸入是什麼,也就是從頁面中取出哪些值進行計算,這個不肯定。我猜想csdn取得就是webflow的流水號,你能夠看csdn的登陸頁面的源碼。第二,運算過程怎麼樣,也不知道。
這個時候,只能用python執行js程序。這個時候想到了node.js。
具體過程不在展開。你會發現遇到一個問題,就是直接調用混淆化後的js代碼,會提示window沒有定義。由於node.js中使用的是global做爲全局屬性,而window則是瀏覽器中才有的。
也就是說,會發現無法用node.js執行這些js代碼。因此這種直接用python去模擬這麼複雜的驗證過程,比較困難。選擇採用一些可以模擬瀏覽器的框架。注意,不單純是模擬發送請求,接收返回的urllib包,而是模擬瀏覽器行爲!這些就是針對相似csdn這種有複雜驗證機制的爬蟲。
因而就產生了第三篇博文,
用selenium進行模擬登陸,保存cookie。