范鵬程 涂嘉慶
摘要:該文基于Scrapy框架研究并實(shí)現(xiàn)了爬取溫州租房信息的爬蟲程序,程序采用分布式結(jié)構(gòu),運(yùn)用去重算法去除重復(fù)URL提高爬蟲的效率,并針對反爬蟲策略提出多種解決方法。爬取的信息存儲(chǔ)在MongoDB數(shù)據(jù)庫中,最終通過測試和分析得出位置、朝向?qū)刂葑夥績r(jià)格的影響,得出租房性價(jià)比較高的方案。
關(guān)鍵詞:租房爬蟲;Scrapy框架;分布式;去重策略
中圖分類號:TP274.2? ? 文獻(xiàn)標(biāo)識碼:A
文章編號:1009-3044(2019)18-0004-03
Abstract: Based on the Scrapy framework, this paper studies and implements a crawler program for crawling Wenzhou rental information. The program adopts distributed structure, uses the de-duplication algorithm to remove duplicate URLs to improve the efficiency of crawler, and proposes various solutions for anti-crawler strategy. The crawled information is stored in the MongoDB database. Finally, the influence of location and orientation on the rent price of Wenzhou was obtained through testing and analysis, and gets a cost effective rental solution.
Key words: rent crawler; Scrapy framework; distributed strategy; de-duplication strategy
1 背景
隨著我國房價(jià)的不斷攀升,越來越多人選擇租房,特別是一些經(jīng)濟(jì)發(fā)展比較靠前的城市,目前中國租房的人口已經(jīng)達(dá)到2億多,數(shù)據(jù)顯示有將近三分之二的人通過網(wǎng)絡(luò)來獲取租房信息,有70%左右的房東會(huì)將租房信息掛在網(wǎng)上,但網(wǎng)上租房信息資源比較分散,當(dāng)需要進(jìn)行數(shù)據(jù)分析篩選出性價(jià)比合適的租房信息時(shí)需要消耗大量的時(shí)間去進(jìn)行人工比對,十分不便。
溫州春節(jié)后有大量的外來務(wù)工人員回歸,其中大多數(shù)會(huì)選擇租房,這個(gè)時(shí)間也是各個(gè)高校開學(xué)的時(shí)間,有大量的學(xué)生租房,如何選擇一個(gè)性價(jià)比適合的房子就非常重要,本文基于Scrapy框架設(shè)計(jì)爬蟲程序爬取溫州租房信息,運(yùn)用聚焦爬蟲收集溫州租房信息并篩選和分析,研究租房的朝向、位置對于溫州房價(jià)的影響,如何租房性價(jià)比最高。
2 相關(guān)技術(shù)
2.1 爬蟲技術(shù)
網(wǎng)絡(luò)爬蟲(Web crawler)也叫網(wǎng)絡(luò)蜘蛛(Web spider),螞蟻(ant)[1],是由程序設(shè)計(jì)者編寫的能自動(dòng)抓取網(wǎng)頁信息并加以解析存儲(chǔ)的程序。一般先指定一個(gè)或多個(gè)初始的URL作為種子,在不斷抓取網(wǎng)頁信息的過程中將爬取到的新 URL存入U(xiǎn)RL訪問隊(duì)列中,在爬取完當(dāng)前網(wǎng)頁資源后從URL訪問隊(duì)列中調(diào)出一個(gè)再次進(jìn)行爬取,一直重復(fù)到滿足程序設(shè)計(jì)者的停止條件或者爬完URL隊(duì)列為止,爬取出的網(wǎng)頁資源會(huì)進(jìn)行一定的解析、篩選然后存儲(chǔ)入數(shù)據(jù)庫中。本文研究的主要是聚集網(wǎng)絡(luò)爬蟲,聚焦網(wǎng)絡(luò)爬蟲顧名思義就是聚焦于一個(gè)主題,將與主題相關(guān)的網(wǎng)頁資源爬取并保存下來的爬蟲。
2.2 Scrapy框架
Scrapy是Python編寫的Crawler Framework,具有結(jié)構(gòu)簡單、使用方便等特點(diǎn)[1]。Scrapy框架包含并發(fā)、存儲(chǔ)、監(jiān)控等功能,并且框架提供基于Twisted異步的爬取,吞吐量十分可觀,爬取速度更快。
其基本工作原理就是Scrapy Engine作為大腦控制Spiders,Spiders讓Scheduler調(diào)出隊(duì)首的URL給Downloader,Downloader去網(wǎng)上下載相關(guān)的網(wǎng)頁資源交給Spiders對資源進(jìn)行分析、篩選,再轉(zhuǎn)交給Item Pipeline進(jìn)行數(shù)據(jù)庫保存,而在URL中解析出來的新的URL將被存入Scheduler的隊(duì)列中,循環(huán)上述抓取步驟,當(dāng)Scheduler的隊(duì)列為空停止。
2.3 分布式爬蟲
分布式爬蟲的構(gòu)架通常由一個(gè)Master服務(wù)器和若干個(gè)Slave服務(wù)器組成,Master服務(wù)器管理Redis數(shù)據(jù)庫中URL隊(duì)列,每當(dāng)一個(gè)Slave服務(wù)器中的Scrapy爬蟲完成網(wǎng)頁資源的爬取,Master就會(huì)再分配一個(gè)隊(duì)首URL給Slave服務(wù)器,使爬蟲繼續(xù)爬行,而在爬取網(wǎng)站資源的過程中遇到的新URL則會(huì)繼續(xù)添加到Redis數(shù)據(jù)庫隊(duì)列中,當(dāng)Redis數(shù)據(jù)庫為空或者滿足設(shè)定值時(shí)就停止爬取。這種分布式的構(gòu)架讓多個(gè)爬蟲公用一個(gè)URL隊(duì)列,極大程度上加快了爬取效率,解決了Scrapy的單機(jī)局限性。
2.4 布隆去重
布隆過濾器是由巴頓布?。˙urton Howard Bloom)于1970年提出的一種基于多個(gè)哈希函數(shù)映射壓縮參數(shù)空間的數(shù)據(jù)結(jié)構(gòu)[2],是一種二進(jìn)制向量數(shù)據(jù)結(jié)構(gòu),主要的功能是判斷一個(gè)元素在不在一個(gè)集合內(nèi),爬取網(wǎng)站的過程中需要保存大量的URL,當(dāng)獲得一個(gè)新的URL時(shí),需要先判斷這個(gè)URL是不是已經(jīng)爬取過了,如果已經(jīng)存在了將跳過這個(gè)URL,不再進(jìn)行保存。
布隆去重是內(nèi)存去重的一種方法,不必在每一次判斷的時(shí)候都去調(diào)用數(shù)據(jù)庫查詢,而是在最初創(chuàng)建一個(gè)空的Bitmap集合,將得到的URL拆成多段,利用哈希算法生成相應(yīng)個(gè)數(shù)的哈希值,然后將其映射到Bitmap集合中,若下一個(gè)URL拆封成多端經(jīng)過哈希算法運(yùn)算映射到Bitmap集合位置上的數(shù)值不全為1,則說明這個(gè)URL沒有被訪問過,若數(shù)值全為1則可能訪問過也有可能沒有訪問過,所以這一種算法會(huì)有一定的誤判率,但是卻能帶來存儲(chǔ)空間的極大節(jié)省。
2.5 反爬蟲策略
當(dāng)運(yùn)行爬蟲對網(wǎng)站進(jìn)行訪問時(shí),網(wǎng)站會(huì)在后臺對訪問進(jìn)行統(tǒng)計(jì),設(shè)定單個(gè)IP訪問的閾值,如果一個(gè)IP地址在短時(shí)間內(nèi)訪問頻率超過閾值,可以暫時(shí)對這個(gè)IP予以封鎖[3],從而導(dǎo)致爬蟲無法正常運(yùn)行,最終爬取信息失敗,所以可以合理的切換代理IP和使用分布式爬蟲來解決此問題。
當(dāng)在一個(gè)網(wǎng)站訪問次數(shù)過多時(shí)網(wǎng)站會(huì)彈出驗(yàn)證碼,輸入錯(cuò)誤會(huì)導(dǎo)致爬蟲不能繼續(xù)爬取,可以利用第三方庫tesserocr來解決一部分容易識別的驗(yàn)證碼,有背景的驗(yàn)證碼則需要先對圖片灰度化,這樣的識別率會(huì)更高。
3 爬蟲設(shè)計(jì)與實(shí)現(xiàn)
3.1 目標(biāo)網(wǎng)站選取
租房的房源一定要真實(shí)可靠,現(xiàn)在比較大且知名的租房網(wǎng)站有58同城、趕集網(wǎng)等,通過研究發(fā)現(xiàn),58同城中的房源信息與其他網(wǎng)站有很高的重復(fù)率,而且58同城的租房網(wǎng)站中的價(jià)格參數(shù)并不能直接從爬取的HTML代碼中能得到,其中價(jià)格參數(shù)是通過Base64加密以后存放在JS中,每次刷新網(wǎng)頁時(shí)其中的映射關(guān)系都會(huì)再次發(fā)生改變,所以獲取價(jià)格都需要重新解密映射,浪費(fèi)了時(shí)間又十分不便,趕集網(wǎng)中數(shù)據(jù)對比與58同城的租房數(shù)據(jù)有很高的重合率,沒有加密和JS渲染,可以提高爬蟲效率同時(shí)又降低了爬蟲制作難度,所以選取趕集網(wǎng)進(jìn)行爬取。
3.2 爬蟲爬取流程
爬蟲開始爬取時(shí)需要一個(gè)或若干個(gè)鏈接作為種子,作為種子鏈接的網(wǎng)頁資源可以繼續(xù)拆封為若干個(gè)分頁鏈接,將鏈接放入一個(gè)隊(duì)列中,爬取到的租房信息存儲(chǔ)到數(shù)據(jù)庫中,若有下一頁則將下一頁的URL放入訪問的隊(duì)列中,循環(huán)這個(gè)過程直到隊(duì)列為空或滿足停止條件停止爬蟲,流程圖如下:
3.3 數(shù)據(jù)采集
3.3.1 Item設(shè)計(jì)
Item是Scrapy框架中的一種簡單容器,將抓取有一定關(guān)聯(lián)的非結(jié)構(gòu)化數(shù)據(jù)保存成結(jié)構(gòu)化數(shù)據(jù),用于Pipelines數(shù)據(jù)庫存儲(chǔ)操作。
Scrapy框架中Field對象可以接收所有的參數(shù)類型,沒有值的限制,也沒有任何屬性。本文需要Field保存的租房參數(shù)有房間數(shù)、平方、朝向、裝修程度、地點(diǎn)、來源、價(jià)格等信息。
3.3.2 Spider設(shè)計(jì)
Spider中首先確定爬取的初始URL:wenzhou.ganji.com/zufang/,其中又分為鹿城、平陽、龍灣、甌海等地區(qū),其URL格式為wenzhou.ganji.com/lucheng/chuzu/只用改動(dòng)URL后綴參數(shù)就能更改地區(qū),實(shí)現(xiàn)爬取不同地區(qū)的信息。
每個(gè)URL中會(huì)有多組數(shù)據(jù),先利用Xpath對所需鏈接進(jìn)行定位,Spider爬取并記錄下鏈接,進(jìn)入鏈接打包所需參數(shù)到一個(gè)Item對象轉(zhuǎn)交給Pipelines,最后搜尋是否有下一頁的鏈接,若有則加入訪問的隊(duì)列,若沒有則切換地區(qū)進(jìn)行爬取。
3.3.3 Middlewares設(shè)計(jì)
Middlewares.py中間件中設(shè)置IP代理可以有效防止同IP訪問次數(shù)過于頻繁而彈出驗(yàn)證碼,在設(shè)置代理IP前首先需要獲得大量IP代理,許多網(wǎng)站有免費(fèi)提供代理IP的服務(wù),可以寫一個(gè)簡單的爬取程序?qū)⒎€(wěn)定可用的IP爬取保留下來。
爬蟲程序添加IP代理時(shí)需先在Setting配置文件中新增加IP池,池中加入用于切換的IP,Middlewares配置文件中設(shè)置Proxy對每次進(jìn)行網(wǎng)站訪問的IP進(jìn)行變更,保證不連續(xù)使用同一個(gè)IP多次訪問網(wǎng)站,當(dāng)使用代理IP進(jìn)行訪問返回403錯(cuò)誤時(shí),說明這個(gè)IP已經(jīng)失效了,需要切換IP代理。
3.4 數(shù)據(jù)存儲(chǔ)
MongoDB是由C++語言編寫的,是一個(gè)基于分布式文件存儲(chǔ)的開源數(shù)據(jù)庫系統(tǒng)[3],在爬取數(shù)據(jù)存儲(chǔ)數(shù)據(jù)庫時(shí)不必關(guān)心表結(jié)構(gòu),可直接將字典結(jié)構(gòu)的數(shù)據(jù)插入,十分方便。
Scrapy框架中運(yùn)用MongoDB數(shù)據(jù)庫需要先編寫Settings,將MongoDB的連接參數(shù)寫入,在Piplines文件中加入MongoDBPipline類用于連接數(shù)據(jù)庫,在其中實(shí)現(xiàn)打開,關(guān)閉以及插入數(shù)據(jù)等方法,最后在插入方法中實(shí)現(xiàn)Item插入數(shù)據(jù)庫的方法,將爬取到的溫州租房信息插入數(shù)據(jù)庫保存。
3.5 數(shù)據(jù)分析
1)從溫州各區(qū)租房信息數(shù)量上看,租房信息最豐富的地區(qū)為鹿城區(qū),占53%,甌海區(qū)和龍灣區(qū)次之,分別占16%和10%,其余地方占據(jù)21%。
2)從月每平方米單價(jià)上看,鹿城區(qū)的平均單價(jià)最高,達(dá)到43.96元/月/m?,甌海區(qū)排名第二,達(dá)到每月39.85元/月/m?,龍灣區(qū)排名第三,達(dá)到35.8元/月/m?,圖中也能看出朝向?qū)τ谄骄鶈蝺r(jià)有一定的影響,朝北的房子一般比朝南的房子低大約2.47~8.65元/月/m?不等,其中對于甌海區(qū)的影響最大。
3)從溫州熱門地區(qū)租房價(jià)格圖上看,鹿城區(qū)的價(jià)格排名第一,其中以裝修精美的安瀾小區(qū)的84元/月/m?在溫州排名最高,甌海區(qū)排名第二,以新鑫小區(qū)61.32元/月/m?在甌海區(qū)排名最高,本文主要分析最熱門的溫州鹿城區(qū):
4 結(jié)束語
溫州租房性價(jià)比高的地區(qū)分別為鹿城區(qū)的東部西部、甌海區(qū)的茶山附近、龍灣區(qū)的海濱和狀元附近、瑞安市的安陽附近、樂清的柳市和翁洋地區(qū)附近、永嘉的甌北附近,這些地區(qū)可以選擇朝南裝修稍好的房子,若需在鹿城區(qū)的南部、北部以及市中心位置租房,由于基礎(chǔ)房租較高,可以選擇不朝南且裝修一般的房子,這兩種選擇方法性價(jià)比最高。
本文基于Scrapy框架編寫了溫州租房信息爬蟲,通過數(shù)據(jù)比對分析篩選出具有性價(jià)比的溫州租房位置,研究出朝向?qū)Ψ績r(jià)的影響,但也存在一些問題,在爬取網(wǎng)頁時(shí)Scrapy框架不支持具有JS渲染的網(wǎng)頁,布隆去重有一定的誤判率等,后續(xù)研究可以針對這幾個(gè)問題進(jìn)行完善。
參考文獻(xiàn):
[1] 馬聯(lián)帥. 基于Scrapy的分布式網(wǎng)絡(luò)新聞抓取系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[D]. 西安: 西安電子科技大學(xué), 2015.
[2] 張笑天. 分布式爬蟲應(yīng)用中布隆過濾器的研究[D]. 沈陽: 沈陽工業(yè)大學(xué), 2017.
[3] 安子建. 基于Scrapy框架的網(wǎng)絡(luò)爬蟲實(shí)現(xiàn)與數(shù)據(jù)抓取分析[D].長春: 吉林大學(xué), 2017.
【通聯(lián)編輯:謝媛媛】