AJAX=Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。通俗來講,AJAX是一種無需加載整個網頁的狀況下,經過在後臺與服務器進行少許數據交換,更新部分網頁的技術,用於建立快速動態網頁的技術。javascript
發送請求能夠利用XMLHttpRequest對象的open()和send()方法。html
方法 | 描述 |
---|---|
open(method,url,async) | 規定請求的類型、URL 以及是否異步處理請求。method:請求的類型;GET 或 POST;url:文件在服務器上的位置;async:true(異步)或 false(同步) |
send(string) | 將請求發送到服務器。string:僅用於 POST 請求 |
服務器的響應須要使用XMLHttpRequest對象的responseText或responseXML屬性。java
屬性 | 描述 |
---|---|
responseText | 得到字符串形式的響應數據。 |
responseXML | 得到 XML 形式的響應數據。 |
下面有一段簡單的代碼:python
<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對象的三個重要的屬性:ajax
屬性 | 描述 |
---|---|
onreadystatechange | 存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。 |
readyState | 存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。0: 請求未初始化;1: 服務器鏈接已創建;2: 請求已接收;3: 請求處理中;4: 請求已完成,且響應已就緒 |
status | 200: "OK";404: 未找到頁面 |
下面咱們從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只不過在對應的節點處更改成服務器返回的內容,這樣原網頁的代碼量不多,可是渲染的時候是經過服務器的響應進行渲染的。json
首先咱們在瀏覽器中進入F12開發者模式,進入存儲並刷新一個頁面(這裏以用FireFox打開微博爲例),會出現不少請求,這實際上就是在頁面加載過程當中瀏覽器與服務器之間發送 Request 和接收 Response 的全部記錄。
而AJAX請求類型爲xhr,能夠看到有下面3條請求,咱們隨便點進去一個進行查看:
api
而咱們全部請求的第一個則是網頁的源代碼,基本上只是寫出了節點,沒有渲染的代碼。當咱們加載新內容的時候,會出現新的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請求的模擬,從而實現數據的抓取。服務器
首先分析一下上面筆者列出的三個請求地址,發現地址都包含有type、value、containerid與page,前兩個地址加上page=1也是能夠請求的,瀏覽器自動省略了而已。觀察一下這些請求,發現它們的 type、value、containerid 始終如一。type 始終爲 uid,value的值就是頁面的連接中的數字,其實這就是用戶的 id,另外還有一個containerid,通過觀察發現它就是 107603 而後加上用戶id。因此改變的值就是 page,很明顯這個參數就是用來控制分頁的,page=1 表明第一頁,page=2 表明第二頁,以此類推。
那麼咱們只須要以這些參數做爲請求參數請求而後抓取json數據就好了。網絡