1. 程式人生 > >Python網絡爬蟲(三)

Python網絡爬蟲(三)

測試 角度 變化 span method 屬性設置 view window nco

AJAX學習

AJAX=Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。通俗來說,AJAX是一種無需加載整個網頁的情況下,通過在後臺與服務器進行少量數據交換,更新部分網頁的技術,用於創建快速動態網頁的技術。

向服務器發送請求與服務器的響應

發送請求可以利用XMLHttpRequest對象的open()和send()方法。

方法 描述
open(method,url,async) 規定請求的類型、URL 以及是否異步處理請求。method:請求的類型;GET 或 POST;url:文件在服務器上的位置;async:true(異步)或 false(同步)
send(string) 將請求發送到服務器。string:僅用於 POST 請求

服務器的響應需要使用XMLHttpRequest對象的responseText或responseXML屬性。

屬性 描述
responseText 獲得字符串形式的響應數據。
responseXML 獲得 XML 形式的響應數據。

下面有一段簡單的代碼:

<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
var xmlhttp;
if
(window.XMLHttpRequest) { xmlhttp=new XMLHttpRequest(); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("myDiv").innerHTML=xmlhttp.responseText; } if(xmlhttp.status==404) { document.write("The file doesn't exist."
); } } xmlhttp.open("POST","/ajax/demo.asp",true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send("fname=Bill&lname=Gates"); } </script> </head> <body> <h2>我的一個測試案例</h2> <button type="button" onclick="loadXMLDoc()">發出請求</button> <div id="myDiv"></div> </body> </html>

可以在w3wschool測試網站看到相應的用法。
代碼中有xmlhttp.onreadystatechange=function(),其中的onreadystatechange是一個事件,意思為當readyState發生改變時,onreadystatechange事件會自動觸發。下面是XMLHttpRequest對象的三個重要的屬性:

屬性 描述
onreadystatechange 存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。
readyState 存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。0: 請求未初始化;1: 服務器連接已建立;2: 請求已接收;3: 請求處理中;4: 請求已完成,且響應已就緒
status 200: "OK";404: 未找到頁面

技術分享圖片

網絡爬蟲相關

python角度分析AJAX

下面我們從python爬蟲的角度對AJAX進行思考,可以分為發送請求->解析內容->渲染網頁三個步驟。其中發送請求,是使用javascript的代碼進行實現,新建了XMLHttpRequest對象,然後利用onreadystatechange屬性設置了監聽,然後再用open()和send()方法發送請求,而我們在python中是請求後直接可以得到響應結果。解析內容是在發送請求並收到服務器的響應後,onreadystatechange事件又再一次被觸發,此時利用xmlhttp的responseText屬性就可以獲取響應的內容。類似於 Python 中利用 Requests向服務器發起了一個請求,然後得到響應的過程。那麽返回內容可能是 HTML,可能是 Json,接下來只需要在方法中用 JavaScript 進一步處理即可。最後一個步驟是渲染網頁,我們都知道javascript可以更改網頁內容,而代碼中document.getElementById().innerHTM這樣的操作就是對某個元素內的源代碼進行更改,這樣網頁顯示的內容就發生了改變;這是對Document網頁文檔進行了操作,即DOM操作。在python中我們同樣的也是利用beautifulsoup庫解析了網頁後,查找其中的節點然後進行提取,AJAX只不過在對應的節點處更改為服務器返回的內容,這樣原網頁的代碼量很少,但是渲染的時候是通過服務器的響應進行渲染的。

AJAX分析

首先我們在瀏覽器中進入F12開發者模式,進入存儲並刷新一個頁面(這裏以用FireFox打開微博為例),會出現很多請求,這實際上就是在頁面加載過程中瀏覽器與服務器之間發送 Request 和接收 Response 的所有記錄。
技術分享圖片
而AJAX請求類型為xhr,可以看到有下面3條請求,我們隨便點進去一個進行查看:
技術分享圖片

技術分享圖片
而我們所有請求的第一個則是網頁的源代碼,基本上只是寫出了節點,沒有渲染的代碼。當我們加載新內容的時候,會出現新的AJAX請求,比如筆者這裏提供三個請求地址:

https://m.weibo.cn/api/container/getIndex?type=uid&value=2145291155&containerid=1005052145291155

https://m.weibo.cn/api/container/getIndex?type=uid&value=2145291155&containerid=1076032145291155

https://m.weibo.cn/api/container/getIndex?type=uid&value=2145291155&containerid=1076032145291155&page=2

每次更新都會有新的請求。所以我們需要利用python來實現AJAX請求的模擬,從而實現數據的抓取。

Python提取AJAX數據

首先分析一下上面筆者列出的三個請求地址,發現地址都包含有type、value、containerid與page,前兩個地址加上page=1也是可以請求的,瀏覽器自動省略了而已。觀察一下這些請求,發現它們的 type、value、containerid 始終如一。type 始終為 uid,value的值就是頁面的鏈接中的數字,其實這就是用戶的 id,另外還有一個containerid,經過觀察發現它就是 107603 然後加上用戶id。所以改變的值就是 page,很明顯這個參數就是用來控制分頁的,page=1 代表第一頁,page=2 代表第二頁,以此類推。
技術分享圖片
那麽我們只需要以這些參數作為請求參數請求然後抓取json數據就行了。

Python網絡爬蟲(三)