上一節(jié),我們使用Charles記錄微博的登錄過程,并從中解析出了微博的登錄細(xì)節(jié),還用Python模擬實(shí)現(xiàn)了整個過程。只要微博登錄不改變,我們的代碼就一直可用,這也算是一勞永逸的事情了,而且程序運(yùn)行中不需要人工參與,高度自動化。記得之前微博還是有驗(yàn)證碼的,這次重新實(shí)現(xiàn)的這個過程中沒有發(fā)現(xiàn)驗(yàn)證碼的蛛絲馬跡。 完全用Python實(shí)現(xiàn)模擬登錄的過程其實(shí)是很累的,考驗(yàn)的是耐力、觀察力、聯(lián)想能力等等。雖然累,但一旦完成后面就省心了,也算是值得一試。 然而世事無常,并非所有登錄都像微博那樣無驗(yàn)證碼(也許有,只是沒有跳出來),更多的是像12306,知乎,嗶哩嗶哩那樣上了變態(tài)的驗(yàn)證碼的。有時候?yàn)榱俗詣幼R別驗(yàn)證碼耗費(fèi)的精力之大難以想象,所以我們寫爬蟲時,要綜合考量投入產(chǎn)出比,人工輸入驗(yàn)證碼可能是更快捷便利的方法。 今天,我們就介紹一款專門從瀏覽器緩存的cookies獲取cookies的工具,一個Python的模塊:browsercookie。 它是一個很有用的爬蟲工具,通過加載你瀏覽器的cookies到一個cookiejar對象里面,讓你輕松下載需要登錄的網(wǎng)頁內(nèi)容。 browsercookie 的安裝 它的源代碼在bitbucket上: browsercookie 可以從源碼安裝,或者直接pip安裝 pip install browsercookie
需要注意的是,在Windows系統(tǒng)下,內(nèi)置的sqlite模塊在加載FireFox數(shù)據(jù)庫時會拋出錯誤。需要更新sqlite的版本: pip install pysqlite browsercookie 的使用我們拿百度的首頁來做實(shí)驗(yàn),如果沒有登錄cookies,打開的首頁右上角菜單欄顯示登錄而不顯示用戶名,如果有登錄cookies,首頁則顯示用戶名而不顯示登錄,通過在得到的html中搜索“登錄”來驗(yàn)證這兩者的不同準(zhǔn)備工作就是,要先打開瀏覽器(比如Chrome, 或Firefox)登錄一下百度,然后就可以關(guān)掉瀏覽器了,當(dāng)然開著也無所謂。 首先,我們看看未登錄狀態(tài)下得到的標(biāo)題: In [1]: import requests
In [2]: url = 'https://baidu.com/'
In [3]: r1 = requests.get(url)
In [4]: r1.content.decode('utf-8').find('登錄')
Out[4]: 1580
In [5]: r1.content.decode('utf8').find('user-name')
Out[5]: -1
由上面的實(shí)驗(yàn)我們看出來,沒有cookies請求得到登錄的信息,‘user-name’是顯示登錄名時的css的class,通過查找user-name再次確認(rèn)沒有登錄。 然后,在看看從瀏覽器獲得cookies后得到的標(biāo)題: In [11]: cjff = browsercookie.firefox() In [12]: header = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'} In [13]: r2 = requests.get(url, cookies=cjff, headers=header) In [14]: r2.content.decode('utf8').find('登錄') Out[14]: -1 In [15]: r2.content.decode('utf8').find('user-name') Out[15]: 5038 通過上面的代碼,我們驗(yàn)證了從browsercookie獲取cookies并成功登錄的百度。 細(xì)心的小猿們可能已經(jīng)發(fā)現(xiàn)了,我用的cookies是從Firefox那里得來的 <code>cjff = browsercookie.firefox()</code>。 原因是,我先實(shí)驗(yàn)從Chrome那里獲取cookies,得到的cookies里面確實(shí)也包含百度,但是就是不能登錄,于是改用Firefox就輕松登錄了。 browsercookie 的缺憾 前面我們也提到了從Chrome獲得的cookies不能登錄百度的問題,后來我又實(shí)驗(yàn)了幾個不同的網(wǎng)站,有的可以也有不可以的,再次證明了這個模塊的不完美。 不過,這個庫用起來很簡單,幾行代碼就可以驗(yàn)證它對我們要登錄的網(wǎng)站是否起作用,所以,寫爬蟲遇到登錄的問題不妨先拿它驗(yàn)證一下,萬一行呢,不就省了很多精力。 還有一類問題,就是你得到了cookies,訪問任何該網(wǎng)站的URL,它都先返回一段登錄驗(yàn)證的html,里面通過JS重定向到不同的網(wǎng)址,你需要進(jìn)一步解析這段JS代碼才能訪問到你真正想訪問的目標(biāo)網(wǎng)址,這樣的操作就比較累人,這樣的網(wǎng)站對爬蟲很不友好。別猜了,我說的就是微博。 <html>
<head>
<title>新浪通行證</title>
<meta http-equiv='refresh' content='0; url='https://login.sina.com.cn/crossdomain2.php?action=login&entry=miniblog&r=https%3A%2F%2Fpassport.weibo.com%2Fwbsso%2Flogin%3Fssosavestate%3D1574046135%26url%3Dhttps%253A%252F%252Fweibo.com%252Fkaifulee%26display%3D0%26ticket%3DST-MTM3MTQ1MzA0MA%3D%3D-1542510135-gz-E235393C87F25EE4E30B221C2B5F7F37-1%26retcode%3D0&login_time=1542509978&sign=d531a8b4eed9c403''/>
<meta http-equiv='Content-Type' content='text/html; charset=GBK' />
</head>
<body bgcolor='#ffffff' text='#000000' link='#0000cc' vlink='#551a8b' alink='#ff0000'>
<script type='text/javascript' language='javascript'>
location.replace('https://login.sina.com.cn/crossdomain2.php?action=login&entry=miniblog&r=https%3A%2F%2Fpassport.weibo.com%2Fwbsso%2Flogin%3Fssosavestate%3D1574046135%26url%3Dhttps%253A%252F%252Fweibo.com%252Fkaifulee%26display%3D0%26ticket%3DST-MTM3MTQ1MzA0MA%3D%3D-1542510135-gz-E235393C87F25EE4E30B221C2B5F7F37-1%26retcode%3D0&login_time=1542509978&sign=d531a8b4eed9c403');
</script>
</body>
</html>
這種異步加載的網(wǎng)頁越來越多,尤其是前端框架ReactJS, VueJS等框架的出現(xiàn)讓前后端分離,由瀏覽器運(yùn)行JavaScript來渲染前端。這個時候,就需要我們的爬蟲支持JavaScript的運(yùn)行,此時此刻,requests等單純的HTTP協(xié)議庫已經(jīng)無能為力了,我們需要更強(qiáng)大的工具 |
|