Python爬蟲——新浪微博(網頁版)

編程語言 Python 網絡爬蟲 MySQL 青峰科技 2017-05-12

最近事情比較多,所以從上週就開始寫的新浪微博爬蟲一直拖到了現在,不過不得不說新浪微博的反扒,我只想說我真的服氣了。

爬取數據前的準備

向右奔跑老大說這次的就不限制要爬取哪些內容了,但是給一個參考,有興趣的可以搞一搞:

Python爬蟲——新浪微博(網頁版)

參考想法

當我看到這個的時候感覺很有意思和搞頭就想去整一整,所以我的一個想法就是去找一個粉絲比較多的人去解析他的分析信息,然後再去解析他粉絲的粉絲,以此類推(感覺解析初始用戶的關注的人的粉絲會更好一點,因為他的粉絲比較多,他關注的人粉絲量肯定不會小),但是到後來我就想放棄這個想法了,因為遇到的問題真的一大堆,好了廢話不多說,來看一下我抓取的信息:

  • 抓取的信息:

  • 1.微博標題

  • 2.微博nickname

  • 3.標識id

  • 4.微博等級

  • 5.地區

  • 6.畢業院校

  • 7.關注量+URL

  • 8.粉絲量+URL

  • 9.微博量+URL

大致獲取的也就這麼多信息,因為很多人的信息是不完善的,所以就先抓這麼多進行測試。

一個基本的思路

確定了我們要找的信息,接下來就是去解析網頁了(一個大的難題要出現了),在我看來獲取網頁目前遇到的:1.解析源碼,2.抓包(json),但是新浪微博這個就比較煩了,他這個是在js中,並且是未加載的(只能用正則或者selenium模擬瀏覽器了),看到這個之後我想了一段時間並且問了羅羅攀 有沒有其他的方法,不行我就用selenium,他說還是推薦正則,解析快一點,selenium是最後的選擇,沒辦法了只好硬著頭皮去寫正則了,這裡在測試正則是否正確,可以使用在線測試工具,進行正則的測試,不必去一遍又一遍運行代碼。

Python爬蟲——新浪微博(網頁版)

源碼+個人信息

Python爬蟲——新浪微博(網頁版)

關注+粉絲+微博

找到這些信息,盯著源碼一直瞅,看的我頭都大了,其實又快捷的方法ctrl+f

Python爬蟲——新浪微博(網頁版)

搜索框

現在信息的位置我們都清楚在哪了,那麼就是寫匹配信息的正則了,這個只能是自己慢慢去寫,可以練習正則表達式。

URL+粉絲分頁問題

個人主頁URL

我們先來看一個示例:http://weibo.com/p/1005051497035431/home?from=page_100505&mod=TAB&is_hot=1#place,

這個URL,給大家提個醒直接用這個是看不到主頁信息的,但是在代碼的測試源碼中我們能看到一個location重定向的連接,是將#之後的部分替換為&retcode=6102,所以URL應該為:http://weibo.com/p/1005051497035431/home?from=page_100505&mod=TAB&is_hot=1&retcode=6102,

我點擊連接測試了一下,看到的內容和第一條連接一樣,並且還有一點,我們之後獲取的所有連接都要替換#之後的內容,來一個示例吧:

urls = re.findall(r'class=\"t_link S_txt1\" href=\"(.*?)\"',data)

如果不進行替換,我們拿獲取後的仍然是無法獲取到我們要的源碼。

粉絲分頁問題

我本想可以解析一個人的粉絲,就可以獲取大量的數據,可還是栽在了系統限制(我在爬取的時候第五頁之後就返回不到數據)

Python爬蟲——新浪微博(網頁版)

系統限制

看到這個之後,系統限制,這個又是什麼,好吧只能看100個粉絲的信息,沒辦法了也只能繼續寫下去。所以說我們只要考慮5頁的數據,總頁數大於5頁按五頁對待,小於5頁的正常去寫就可以,這個搞明白之後,就是要去解決分頁的連接了,通過三條URL進行對比:

  • 1.http://weibo.com/p/1005051110411735/follow?relate=fans&from=100505&wvr=6&mod=headfans&current=fans#place

  • 2.http://weibo.com/p/1005051110411735/follow?relate=fans&page=2#Pl_Official_HisRelation__60

  • 2.http://weibo.com/p/1005051110411735/follow?relate=fans&page=3#Pl_Official_HisRelation__60

通過這兩個URL我們可以看出,差別就在後半部分,除了之前我說的要將是將#之後的部分替換為&retcode=6102,之外還要改動一點,就是follow?之後的內容那麼改動後,我們就從第二頁去構造URL。

示例代碼:

urls = ['http://weibo.com/p/1005051497035431/follow?relate=fans&page={}&retcode=6102'.format(i) for i in range(2,int(pages)+1)]

那麼URL分頁問題就搞定了,也可以說解決了一個難題。如果你認為新浪微博只有這些反扒的話,就太天真了,讓我們接著往下看。

佈滿荊棘的路

整個獲取過程就是各種坑,之前主要是說了數據的獲取方式和URL及粉絲分頁的問題,現在我們來看一下新浪微博的一些反扒:

首先,在請求的時候必須加cookies進行身份驗證,這個挺正常的,但是在這來說他真的不是萬能的,因為cookie也是有生存期的,這個在獲取個人信息的時候還沒什麼問題,但是在獲取粉絲頁面信息的時候就出現了過期的問題,那該怎麼解決呢,想了很久,最後通過selenium模擬登錄解決了,這個之後在詳細說,總之,這一點要注意。

然後,另外一個點,不是每一個人的源碼都是一樣的,怎麼說呢最明顯的自己可以去對比下,登錄微博後看一下自己粉絲的分頁那部分源碼和你搜索的那個用戶的源碼一樣不,除此之外其他的源碼信息也有不一樣,我真的指向說一句,大公司就是厲害。

Python爬蟲——新浪微博(網頁版)

用戶源碼

Python爬蟲——新浪微博(網頁版)

自己本人的源碼

大家自習看應該可以看出來不同,所以整體來說新浪微博挺難爬。

代碼

代碼這一塊,確實沒整好,問題也比較多,但是可以把核心代碼貼出來供大家參考和探討(感覺自己寫的有點亂)

說一下代碼結構,兩個主類和三個輔助類:

兩個主類:第一個類去解析粉絲id,另一個類去解析詳細信息(解析的時候會判斷id是否解析過)

三個輔助類:第一個去模擬登陸返回cookies(再爬取數據的過程中,好像是隻調用了一次,可能是代碼的問題),第二個輔助類去返回一個隨機代理,第三個輔助類將個人信息寫入MySQL。

下邊我就將兩個主類的源碼貼出來,把輔助類相關其他的信息去掉仍然是可以運行的。

1.fansSpider.py

#-*- coding:utf-8 -*-import requestsimport reimport randomfrom proxy import Proxyfrom getCookie import COOKIEfrom time import sleepfrom store_mysql import Mysqlfrom weibo_spider import weiboSpiderclass fansSpider(object):

中間註釋的一部分,因為代碼在調試,大家參考正則和一些處理方式即可

2.weibo_spider.py

# -*- coding:utf-8 -*-import requestsimport refrom store_mysql import Mysqlimport MySQLdbclass weiboSpider(object):

寫的比較亂,大家將就著看,還是我說的只是一個Demo

輔助類之一(存mysql,可以參考Mr_Cxy的python對Mysql數據庫的操作小例),其他的兩個關於隨機代理和獲取cookie,在下篇文章會詳細講解

運行結果+數據結果

Python爬蟲——新浪微博(網頁版)

測試結果

Python爬蟲——新浪微博(網頁版)

運行截圖

200為狀態碼,說明請求成功

Python爬蟲——新浪微博(網頁版)

mysql數據庫存儲結果

總結

目前新浪微博是遇到問題最多的一個,不過也學到了很多知識,比如正則表達式,隨機代理等等,在學習的過程中就是遇到的問題越多,積累的越多,進步越快,所以遇到問題和出錯也是幸事。說一下代碼運行過程中存在遇到的問題吧(可以一塊交流解決):

  • 1.有兩個id一直在循環,可能是循環那一塊存在問題,可以一塊交流,解決後會更新文章。

  • 2.解析的速度(單線程比較慢,後續寫scrapy版)

  • 3.去重(目前是在將解析過的id寫入數據庫,然後在解析前進行判斷)

相關推薦

推薦中...