爬取博主微博內容,遇到展開全文

一開始參考:

https://blog.csdn.net/qq_16546829/article/details/79511997

后來換了:

https://blog.csdn.net/five_east_west/article/details/108627097

Ajax動態分析

待抓取的微博內容:https://m.weibo.cn/u/1742566624

準備工作:安裝好 requests 庫、lxml 庫

在cmd 中輸入


因為我之前已經安裝好這兩個庫,所以在此安裝的時候是顯示的下圖的內容:

分析網頁

打開Chrome瀏覽器,我們進入這個網站:https://m.weibo.cn/u/1742566624。鼠標右鍵,選擇查看網頁源代碼,這時候我們會發現網頁源代碼中并沒有顯示出來我們在首頁看到的那些文字內容,這就說明這個網頁是Ajax動態加載的。(下圖中左邊為展現給我能夠看到的網頁,而右邊則是網頁源代碼)

我們到右邊隨意選擇一條內容到左邊進行搜索都不會有結果,這里以“煙火人間,風味長存。”為栗子進行搜索:

我們看到源代碼中并沒有出現我們搜索的內容,所以該網頁是Ajax動態加載的。

??Ajax,全稱為Asynchronous JavaScript and XML,即異步的JavaScript和XML。它不是一門編程語言,而是利用JavaScript在保證頁面不被刷新、頁面鏈接不改變的情況下與服務器交換數據并更新部分網頁的技術。

對于傳統的網頁,如果想更新其內容,那么必須要刷新整個頁面,但有了Ajax,便可以在頁面不被全部刷新的情況下更新其內容。在這個過程中,頁面實際上是在后臺與服務器進行了數據交互,獲取到數據之后,再利用JavaScript改變網頁,這樣網頁內容就會更新了。

可以到W3School上體驗幾個示例來感受一下:http://www.w3school.com.cn/ajax/ajax_xmlhttprequest_send.asp

其實很多網頁都是這樣的,我們把網頁接著往下滑,會不斷的刷新加載新的內容呈現在我們眼前。

既然我們已經知道它是用Ajax動態加載的,我們就來分析一波它是如何進行數據交換的。

鼠標右鍵,選擇檢查(或者按下鍵盤上的F12),進入開發者模式。網頁的樣式便展示在了我們眼前。

在Elements中我們能看到網頁源代碼,右側是節點的內容,但這并不是我們想要的內容,如果按照常規的網頁請求并提取網頁標簽中的數據是無法得到我們想要的內容的。

我們轉到Network,選擇Network下的XHR,我們會看到以下內容(第一次進入是沒有這些內容的,刷新一下網頁就好了):

隨著我們不斷的滾動鼠標滾輪,XHR下加載的內容越來越多,我們會看到一個getIndex開頭的請求,點開它,可以看到它的詳細信息

我們看到Request Headers它里面有一個參數是X-Requested-With: XMLHttpRequest。通過這個參數我們可以更加肯定它是Ajax動態加載的。然后點一下 Headers 旁邊的 Preview,它里面的數據是 json(類似python字典的一種字符串) 格式的。

點開cards下面有10條內容,我們在進到下面9條內容中的mblog里面去一 一查看,我們會發現,微博正文中包含的文字都包含在了raw_text中

(其實圖片也包含在這個請求中,想要把圖片下載下來的看客朋友可以自己去研究研究圖片的鏈接)。既然已經找到我們想要的東西了,就開始寫BUG吧,把這些文字給“抓”下來,放到自己的“口袋”中。

請求數據

我們用requests.get(url)來請求網頁,因為我們要請求的網頁已經不是開頭給出的那個網頁了,而是通過我們分析之后找到的那個Ajax的網頁請求。所以我們真正請求的應該是這個網頁https://m.weibo.cn/api/container/getIndex?uid=1742566624&t=0&luicode=10000011&lfid=100103type%3D1%26q%3D%E6%80%9D%E6%83%B3%E8%81%9A%E7%84%A6&type=uid&value=1742566624&containerid=1076031742566624,打開這個網頁我們會發現,密密麻麻的字符、數字,我們在瀏覽器中隨便找一個json數據在線解析網址http://json.cn/,這里的這個就可以,將上面網頁的內容復制到json網頁中我們就可以看到整齊的json數據了,很像python中的字典型式。

在jupyter中這樣寫:


我們直接將它轉成json格式,在jupyter中打印出來,隨時查看網頁返回的信息是個什么樣子的東西。(爬蟲、數據分析等建議使用jupyter,方便隨時查看結果)

運行上述代碼,得到以下輸出:

不難發現,這個數據就和我們之前在 Preview 中看到的數據是一樣的,說明我們拿到的就是我們想要的數據,接下來將我們要的微博正文內容從這個字典從取出來就行了。代碼如下:


運行結果如下:

因為cards是一個列表,它里面包含了十條數據,所以我們用一個for循環來遍歷整個列表,將數據從提取出來,因為我們返回的數據是字典類型的,所以我們可以直接用get來提取數據,或者按照鍵值對來索引(建議使用get,如果沒有當前鍵而進行索引會報錯,而get是返回一個空值,不會使程序出錯停下來)。就這樣,我們提取了“第一頁”的十條數據,但這個數據量往往不能滿足我們的需求。

獲取多頁數據

如果我們一個網頁一個網頁的去復制粘貼到到我們的腳本中,10個可能問題還不大,先找到getIndex然后將網頁復制,粘貼到腳本中,總共三步,10個網頁也就30步,可如果是100個網頁呢?這時候處理起來就比較麻煩了。所以我們需要找到一個構造網頁的“好方法”,讓腳本它自己去“ 尋 找 網 頁 ” → “ 復 制 ” → “ 粘 貼 ” “尋找網頁”\rightarrow“復制”\rightarrow“粘貼”“尋找網頁”→“復制”→“粘貼”,一般面對這種重復的工作我們都可以交給程序來完成。所以我們現在要做的就是”教會“我們的爬蟲腳本去做這個事情。

在回過頭來看看我們請求的網頁:https://m.weibo.cn/api/container/getIndex?uid=1742566624&t=0&luicode=10000011&lfid=100103type%3D1%26q%3D%E6%80%9D%E6%83%B3%E8%81%9A%E7%84%A6&type=uid&value=1742566624&containerid=1076031742566624這是我們請求的第一個網頁,我們再來看看第二個我們要請求的網頁長得怎么樣:https://m.weibo.cn/api/container/getIndex?uid=1742566624&t=0&luicode=10000011&lfid=100103type%3D1%26q%3D%E6%80%9D%E6%83%B3%E8%81%9A%E7%84%A6&type=uid&value=1742566624&containerid=1076031742566624&since_id=4551744417694196。第二個網頁好像和第一個網頁不太一樣,它比第一個網頁要多出一個小尾巴since_id,其實我們再去看第三個、第四個、第五個……從第二個網頁開始,它們都有了一個since_id的參數,所以我們只要在第一個網頁的基礎上給往后的每個網頁都加上一個since_id的參數就行。但是好像每個網頁對應的since_id 都是不一樣的,所以我們如果是想胡謅一個的方法貌似是行不通的。但是,它這個網頁畢竟是人寫的,不是神創的,所以它這個since_id一定是有辦法通過我們聰明的小腦袋瓜”造“出來的。

既然它這個網頁的since_id要被瀏覽器抓到,并不斷請求下一頁數據,那么這個since_id被我們自己找出來也不會是難事。

果然,我們可以在json數據的cardlistInfo中找到一個since_id的鍵

我們將這個since_id和下一個網頁中的since_id 進行比較,它兩就是一樣的(我這里截的是首頁的since_id,隨著時間變化這個since_id也會變化,看客朋友看到的和我的不一樣是正常的),我們像提取文本信息一樣用get將since_id 獲取下來。現在我們找到了這個since_id 的構造規律,我們就可以來請求多頁的網頁數據了,我們只要教會我們的爬蟲腳本如何利用我們為它找出來的since_id來構造網頁,它就能不斷的獲取網頁上的內容了。

??構造網頁的代碼如下:


urlencode是在urllib.parse中的方法,以下是官方文檔:

函數中傳入的since_id就是我們為爬蟲找到的since_id。然后我們把構造好的網頁返回給網頁請求函數,在解析提取我們要的內容以及since_id,這樣就可以一直不停的循環下去了。

存儲數據

??寫個爬蟲,應該不會只是為了爬一爬數據,而且我們如果下次還要用這個數據又要重新爬,也會很麻煩,所以我們將我們從網絡上”竊取“下來的東西”藏“起來。這里我們用記事本將這些文本數據存下來(當然也可以寫到數據庫里面去,感興趣的看客老爺可以自己去網上搜搜寫入數據庫的操作)。保存數據代碼如下:


因為我們這里抓取的是思想聚焦的微博文章,所以寫入的標題就是”思想聚焦的微博正文“,然后每寫完一行都空一行(這樣看起來工整一些)參數newline就是這個作用。

到這兒我們的爬蟲也就寫完了,感興趣的可以做做詞云圖、做一下情感分析等……

完整代碼:


在這個腳本腳本中我們設置了請求頭,讓我們的爬蟲看上去更像是瀏覽器在訪問。

運行結果:

總結:

我們檢查網頁源代碼時,發現源代碼中沒有我們在網頁上看到的信息時我們就要想到它時Ajax動態加載的。對于Ajax的網頁的抓取我們應該要去分析它的動態加載包,而不是直接請求它的源代碼,通過構造Ajax網頁網址來實現多頁信息的抓取,不同的網站它的url的構造方法不一樣,這一點需要看客朋友自己去找規律,構造url。看完這篇文章如果你覺得你會爬取Ajax的網頁了,可以去試試爬取今日頭條上面的內容,它也是Ajax加載的。

??提取網頁信息的方法也是有很多種,只是在這個栗子中我們這個恰巧是字典形式,如果遇到其他情況我們要隨機應變,自己最熟悉的信息提取方式將網頁信息抓取下來。就介紹到這里吧,有些簡陋,但大致能看。

————————————————————————————————————————

但是遇到有展開全文的博文時,


raw_text后面就沒有了


text后面有

通過判斷text后面是否有“全文”兩字,若有,則導出前面的那串數字,通過新的地址(全文地址),拿到全文。(常常有tag,爬下來的全文中還存在很多地址,需要后續刪減


longTextContent則是全文內容

代碼:


判斷正文函數

用此函數在main中代替上文get_infos(html)

(有點小錯誤還需在改正

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。