嗯,這一篇文章更多是想分享一下我的網頁分析方法。玩爬蟲也快有一年了,基本代碼熟悉之後,我感覺寫一個爬蟲最有意思的莫過于研究其網頁背後的加載過程了,也就是分析過程,對性能沒有特殊要求的情況下,程式設計一般是小事。
以深圳地區的X房網為例吧。XX房網的首頁非常簡潔,輸入相應的地區就可以找到對應的二手房或者一手房。這一篇文章主要就給大家介紹我在做XX房網爬蟲的分析過程。
注意:本文采用Chrome作為分析加載工作,如果使用其他浏覽器,請參考具體的規則。
首先想到的
嗯,你首先要跳出程式設計,從使用者甚至是産品經理的角度去思考:在浏覽這個頁面的時候,如何就能看到全市的二手房的情況。通過首頁的一個區一個區的輸入,搜尋,然後将頁面的單元下載下傳,嗯這是一個方法。

南山區首頁的情況
如上圖所示,隻要更改keyword後面的參數,就可以獲得不同區的二手房資料。程式設計的時候隻需要手動寫入一個含有各個區的list,然後通過循環去更改keyword後面的參數,進而開始一個區域,再爬取其中的連結。這個方法确實是可行的,深圳一共也沒有多少個區。這個方法我試過是可行的。
我實際想說的
上面的這個方法固然可行,但并不是我想推薦的方法,大家看回首頁,搜尋欄旁邊有一個地圖找房。點進去你就能看到深圳全區域的房子,要是能在這裡弄個爬蟲,不就簡單多了。
地圖找房位置
深圳全區域的二手房
可以看到截圖的右側有所有二手房的連結,我們的任務就是下載下傳右邊的所有二手房的資料。首先第一步就先檢視頁面的源代碼(Ctrl+U),可以從右邊連結清單那裡複制一些關鍵字,在源代碼裡面找找看,在源代碼裡面Ctrl+F搜尋觀瀾湖試試,結果是沒有,再嘗試幾個關鍵詞好像都沒有,但通過檢查元素(Ctrl+Shift+I),是可以定位到這些關鍵詞的位置。這樣可以初步判斷右邊的連結清單是通過Js來加載,需要證明。
關鍵詞觀瀾湖的在源代碼裡面的搜尋結果
關鍵詞觀瀾湖的在頁面元素裡面的搜尋結果
嘗試對觀瀾湖上方的元素在源代碼裡面定位,例如no-data-wrap bounce-inup dn,就可以在源代碼裡面找到。仔細對比一下兩邊的上下文,可以看到在節點下面的内容有非常大的差異。通過這個roomList作為關鍵詞繼續查找。
no-data-wrap bounce-inup dn 在檢查元素内的位置
no-data-wrap bounce-inup dn 在源代碼的位置
在檢查元素裡面可以發現roomList下面的加載的内容就是我們所需要的房屋清單,并且這部分内容再源代碼裡面沒有。而在源代碼頁通過搜尋roomList,卻發現出現在script裡面,證明roomList裡面的内容是通過Js來加載的:
源代碼中roomList出現的位置
下面就變成是找這個roomList了,由于是通過js加載的,打開控制台的network,并重新重新整理頁面,檢視頁面裡面各個元素的加載過程,在過濾器裡面輸入roomList,可以找到一條資訊:
roomList的搜尋結果
點開看response裡面下載下傳的内容,發現那不就是我們要找的東西嗎!裡面有給出詳細的頁面數量(roomPageSize),那一個個的八位數字顯然就是每一個房子的id嘛,然後每一頁的加載數量是一定的,下面有對應id裡面有房子的經緯度、戶型、面積以及朝向等等資訊(在這裡做一個提醒,需要做heatmap的同學注意了,這裡的經緯度用的是百度坐标,如果你後續可視化用的是google地圖、高德或者GPS,是需要轉換坐标的)。
roomList的内容
找到内容之後,接着就是看他的Headers,看看是如何加載的。
Request Url表明其通路的連結,Request Method表明他的請求方法是Post;
Request的頭定義(Headers)裡面包括Host、Origin、Referer、User-Agent等;
請求的參數(parameters)裡面有三個參數,這三個參數是直接放映在其Url連結上面,裡面包括目前頁的頁碼(currentPage)、頁面大小(pageSize)以及s(這個s一開始也不同清楚是什麼,但是發現每一次請求都有變化,後面才知道這個是時間戳,表示1970紀元後經過的浮點秒數);
此外Post函數還可以發送資料到伺服器做請求,這裡所發送的資料包括始末經緯度、gardenId(這個到後期發現是對應的小區編号)和zoom(代表地圖上面放大以及縮小的倍數,數字越大,放大倍數越高)
Header第一頁
Herader第二頁
基本扒到這裡,對整個頁面就比較清晰了,也知道我們的爬蟲要怎麼去寫了。
開始寫代碼了
邏輯整理出來後,整個代碼就寫的非常輕松了。首先通過post方式通路<code>http://shenzhen.XXfang.com/map/sale/roomList</code>,通過正規表達式提取Reponse裡面的roomPageSize,或者最大頁數。然後對每一頁的内容進行爬取,并将資訊輸出。
第一部分,加載庫,需要用到requests, bs4, re, time(time是用來生成時間戳):
from bs4 import BeautifulSoup
<code></code><code>import requests, re, time</code>
<code></code>
第二部分,通過設定合理的post資料以及headers,通過post下載下傳資料。其中payload裡面包括地圖所展示的經緯度資訊(這個資訊怎麼獲得,在X房網頁面上通過滑鼠拖拉,找到合适的位置之後,到控制台Header内檢視此時的經緯度就好了),headers則包含了通路的基本資訊(加上有一定的反爬作用):
頁面下載下傳後,對于第一次下載下傳首先需要用正規表達式獲得最大頁面數,我們真正需要的内容結合Beautiful的get和find以及re來抓取就可以了:
給一個在控制台裡面輸出的效果:
最後的效果
最後,這篇文章給出了我在寫X房網爬蟲的整個分析的思路。
原文釋出時間為:2017-03-11
本文作者:Garfield_Liang