老貓我在南五環租了一個80平兩居室,租房合同立刻到期,房東打電話問續租的事,想要加房租;我想如今國家正在在抑制房價,房子價格沒怎麼漲,房租應該也不會漲,因而霸氣拒絕了,如下是聊天記錄:
確認不續租以後,兩三年沒找過房的我上網搜索租房,沒想到出來一坨自如,蛋殼,貝殼等中介網站;進去看看,各類房照很是漂亮,可是一看房租,想送給本身一首《涼涼》;附近房租竟然比我當前房租高1000多RMB;自我安慰下,這些網站房源價格不是真實的,因而切換到我愛我家,鏈家等大中介平臺,結果發現房租價格都差很少;心想這才幾年,若是兩年前對本身狠點買了房,房租都夠還房貸了。爲了生存,不甘心的我,決定把這些大網站的房源信息抓取下來進行分析,帝都這麼大總有一套適合本身。css
說幹就幹,先找到市場上主要的中介平臺,我主要關注我愛我家、鏈家、貝殼,還有其餘類的長租公寓例如自如,蛋殼等;通過查資料還發現一個問題,好像鏈家、貝殼、自如是一個大老闆,鏈家房源和自如的都是混到一塊兒的,整的我一個頭大;而貝殼相似於京東,不只本身自營,還容許其餘中介商來入住這個平臺,這老闆腦瓜子真是好使,折騰半天把數據都掌握在本身手裏,總感受這些年房價與房租上漲和這個貨有種說不清的關係。html
老貓租住小區門口就有一鏈家,天天西裝革履的經紀人在小區裏晃悠;先從鏈家下手,抓取與分析過程以下:html5
1:查看鏈家房源信息,決定抓取數據;
2:數據請求行爲分析;
3:分析實現這個功能所使用知識點,
4:抓取代碼實現與調試;
5:對出租房源信息進行分析;node
藉助瀏覽器打開鏈家主頁,找到租房菜單,查看要抓取信息;
地址:https://bj.lianjia.com/zufang/ ;
頁面信息以下圖:
從當前信息中能夠看到,鏈家有近19000套在線房源(某些爲單間,一些爲北三縣);
根據頁面信息確認抓取信息,主要包括:所屬小區,戶型,面積,價格,所屬區域,具體地址,房齡,房屋編號及詳情頁地址;確認抓取信息後,分析請求行爲,進行抓取。express
使用瀏覽器打開頁面,查看請求過程,主要分幾步進行抓取:json
1> 請求首頁:https://bj.lianjia.com/zufang/ ;
2>解析北京下屬區域對應url,注意:這裏不包括燕郊與香河;
3>按照行區域逐頁抓取並提取頁面房源信息,直到抓取結束;瀏覽器
整個請求過程以下:
確認抓取過程後,分析抓取過程使用的知識點。app
整個抓取過程分爲請求數據,提取信息,數據保存,老貓這邊使用Python實現,主要知識點以下:echarts
1>請求數據:requests模塊;
2>提取信息:BeautifulSoup模塊;
3>數據保存:csv格式存儲,csv模塊;ide
請求行爲與知識點分析完成後,老貓在Jupyter下完成了單頁數據抓取與信息提取,具體過程這裏不詳細講解,直接上最終代碼。
老貓使用類實現抓取與信息提取,快速描述實現過程:
1>整理思路,確認要作的事情,分步實現;
2>根據請求與提取行爲定義類與相關方法;
3>將Jupyter下實現填充到對應方法中;
4>存儲類實現;
5>代碼調試與運行;
最終代碼以下:
#coding=utf-8 #Author: qimao import requests from bs4 import BeautifulSoup import json import csv import time class CsvSaveModule(object): #存儲csv類 def __init__(self, fname = "info.csv"): self.f = open(fname, 'w', encoding='utf-8') self.fcsv = csv.writer(self.f) self.head = True def write(self, keys, data): #寫入字段 if self.head: self.head = False self.fcsv.writerow(keys) #獲取並寫入數據 values = [data.get(key, "") for key in keys] self.fcsv.writerow(values) def close(self): self.f.close() class SpiderMoujia(object): def __init__(self, *args): 'args:保存數據對象' self.urlhead = 'https://bj.lianjia.com/' self.hds = args def reqPage(self, url): num = 0 #一個頁面最多嘗試請求三次 while num < 3: #請求頁面信息,添加請求異常處理,防止某個頁面請求失敗致使整個抓取結束, try: if url: req = requests.get(url) if req.status_code == 200: #返回BeautifulSoup對象 return BeautifulSoup(req.text, 'html5lib') except: pass time.sleep(3) num += 1 def startCrawler(self, url): #抓取對外接口,Url爲種子url self.startRequest(url) self.close() def startRequest(self, url): #開始抓取 obj = self.reqPage(url) areas = obj.find('div', class_="option-list") #提取區域信息:海淀,朝陽,.... listarea = areas.select('a[href^="/zufang/"]') for area in listarea[1:]: aurl = self.urlhead + area.get('href') district = area.text.strip() #按照區域進行抓取 self.crawlerArea(aurl,district) def crawlerArea(self, url, district): #print('crawlerArea', url) page = self.reqPage(url) if not page: return #解析頁面信息 self.parsePage(page,district) #獲取下一頁地址 nextpage = self.getNextPage(page) if nextpage: urlhead = url.rsplit('/',1)[0] nexturl = '/'.join([urlhead, nextpage]) #繼續請求下一頁 self.crawlerArea(nexturl,district) def extractInfo(self, node, css): snode = node.select_one(css) val = '' if snode and snode.text: val = snode.text.strip() return val def parsePage(self, page,district): #主要功能,提取頁面信息 listhouse = page.select('#house-lst > li') #定義出提取字段 keys = ['信息', '小區', '戶型', '價格', '面積', '區域', '位置', '樓層', '年份', '附加信息', '房屋ID', '詳情頁地址'] for house in listhouse: hinfo = [] #提取title, 小區,戶型,價格,面積 cssexpress = ['h2 a', '.where a', '.zone', '.num','.meters'] info = house.select_one(".info-panel") if not info: continue for express in cssexpress: hinfo.append(self.extractInfo(info, express)) #添加區域 hinfo.append(district) #區域,樓層,年代 hinfo.extend(info.select_one('.con').text.split('/')) #房子其餘信息,例如:地鐵,陽臺,供暖等 spans = info.select_one('.view-label') hpoint = ','.join((spans.stripped_strings)) hinfo.append(hpoint) #房子ID號,惟一標識 hinfo.append(house.get('data-id')) #房租詳情頁url hinfo.append(info.select_one('h2 a').get('href')) #轉換成字典 housedata = dict(zip(keys, hinfo)) print (housedata) self.saveData(housedata) def getNextPage(self, page): try: #獲取下一頁 pagenode = page.select_one('.page-box') pageinfo = pagenode.get('page-data') jdata = json.loads(pageinfo) curpage = jdata.get('curPage') total = jdata.get('totalPage') if (curpage < total): return 'pg%d'%(int(curpage+1)) except: print('error') pass def saveData(self, data): #按照順序保存數據 keys = ['信息', '小區', '戶型', '價格', '面積', '區域', '位置', '樓層', '年份', '附加信息', '房屋ID', '詳情頁地址'] [hd.write(keys, data) for hd in self.hds] def close(self): #列表解析關閉存儲模塊 [hd.close() for hd in self.hds] if __name__ == '__main__': #開始抓取 url = 'https://bj.lianjia.com/zufang/' csvhd = CsvSaveModule('ljinfo.csv') spider = SpiderMoujia(csvhd) spider.startCrawler(url)
運行過程以下圖:
最終獲取了1W多套出租房信息,到這裏我完成鏈家出租房源信息抓取。
我愛我家是一個老牌的房地產中介,老貓來帝都10年了,畢業當年大部分同窗幹了當年認爲比較正統的工做,一個另類同窗去了我愛我家作中介,早些年他常常羣裏發消息,給咱們介紹房源,你們認爲他是推銷,不多有人理他;最近同窗聚會見面我問他:你當年爲何不在使勁逼着我買房?同窗擡起頭,吸了一口煙吐了一圈,說了一句話,讓我感受夏天頓時涼爽了許多:'逼你你也買不起,逼你你也買不起,逼你你也買不起,重要事情說三遍',感受友誼的小船就要翻了。
下面咱們來看我愛我家出租房源頁面信息,以下圖:
從頁面中咱們能夠看到,我愛我家有3.2萬套出租房源,房源信息比較直觀;經過分析發現抓取我愛我家請求行爲與抓取鏈家相似,不一樣之處在於提取數據與提取過程;咱們能夠在基於鏈家爬蟲進行修改實現;具體實現過程在這裏不詳細講解,直接上抓取部分結果:
區域,地址,小區,價格,面積,樓層,裝修,地鐵附近,戶型,朝向,信息,附加信息,詳情 朝陽,望京,寶星國際,8000,64 平米,低樓層/25層,精裝,距離地鐵望京東450米,1 室 1 廳,南,寶星國際緊鄰望京SOHO 阿里巴巴 精裝朝南大開間,"近地鐵,隨時看,拎包入住,押金減免",/zufang/41330436.html 朝陽,望京,炫彩嘉軒,6500,60 平米,中樓層/21層,精裝,距離地鐵望京東760米,1 室 0 廳,南,炫彩一居室老業主委託 我有鑰匙 鄰望京SOHO,"近地鐵,可短租,拎包入住,集中供暖",/zufang/41348206.html 朝陽,望京,寶星國際,8500,64 平米,高樓層/25層,精裝,距離地鐵望京東450米,1 室 1 廳,南北,望京SOHO旁寶星國際,鄰阿里巴巴,綠地,南向大開間,"近地鐵,隨時看,拎包入住,押金減免",/zufang/41331126.html 朝陽,CBD,陽光100國際公寓,9500,48 平米,低樓層/33層,精裝,距離地鐵大望路391米,1 室 1 廳,北,陽光100國際公寓精裝開 二次裝修有鑰匙看房方便,"近地鐵,隨時看,免傭,拎包入住",/zufang/41330729.html 朝陽,望京,朝庭公寓,13000,112 平米,高樓層/27層,精裝,距離地鐵望京南476米,2 室 1 廳,南北,望京南朝庭公寓,鄰悠樂匯和方恆國際,看房有鑰匙,隨時看房,"近地鐵,隨時看,免傭,拎包入住",/zufang/41337320.html 朝陽,石佛營,日月東華,6700,66.3 平米,頂層/21層,精裝,距離地鐵十里堡1072米,1 室 1 廳,南,石佛營新上婚房一居拎包入住 看房預定,"近地鐵,拎包入住,集中供暖",/zufang/41348814.html 朝陽,惠新西街,勝古北里,2800,58 平米,底層/5層,精裝,距離地鐵惠新西街南口232米,3 室 1 廳,北,隨時看 隨時住三家合住正規中臥室精裝修,"近地鐵,隨時看,拎包入住,集中供暖",/zufang/41338276.html 朝陽,潘家園,弘善家園,5300,61 平米,中樓層/13層,精裝,距離地鐵十里河691米,1 室 1 廳,南,十里河 潘家園10號線 弘善家園精裝正規一居 拎包入住,"近地鐵,拎包入住",/zufang/41334177.html 朝陽,東壩,朝陽新城一區,6500,114 平米,中樓層/6層,精裝,,2 室 1 廳,南北,朝陽新城一區兩室一廳,隨時看,/zufang/41351101.html 朝陽,十里堡,十里堡,6000,60 平米,底層/4層,中裝,距離地鐵十里堡781米,2 室 1 廳,南北,6號線 十里堡 南北兩居帶小院子 居家必備,"近地鐵,隨時看,集中供暖",/zufang/41345370.html 朝陽,十里堡,十里堡北里,5000,50 平米,中樓層/13層,中裝,距離地鐵十里堡371米,1 室 1 廳,南北,十里堡 八里莊北里 晨光家園 隨時看,"近地鐵,免傭",/zufang/41342158.html 朝陽,南沙灘,南沙灘小區,7000,65 平米,中樓層/6層,精裝,距離地鐵北沙灘775米,2 室 1 廳,南北,南沙灘 中間層兩居室 臨地鐵北辰中科院 有鑰匙,"近地鐵,隨時看,拎包入住",/zufang/41341943.html 朝陽,管莊,管莊周井大院,6000,72 平米,中樓層/5層,精裝,距離地鐵雙橋604米,3 室 1 廳,南北,管莊周井大院精裝三居室出租 隨時入住,"近地鐵,隨時看,拎包入住,集中供暖",/zufang/41339579.html 朝陽,百子灣,金泰先鋒,10000,92 平米,底層/11層,精裝,距離地鐵百子灣437米,2 室 1 廳,南北,金泰先鋒 南北兩室一廳一廚一衛,"近地鐵,拎包入住,集中供暖",/zufang/41328442.html 朝陽,北苑,蘊實園,5800,66.37 平米,中樓層/14層,精裝,距離地鐵北苑571米,1 室 1 廳,南,鑰匙房源,看房隨時。,"近地鐵,隨時看,拎包入住",/zufang/41349514.html 朝陽,芍藥居,芍藥居,13000,118.38 平米,中樓層/14層,簡裝,距離地鐵芍藥居116米,3 室 1 廳,南,芍藥居南里精裝修三室一廳,"近地鐵,隨時看,拎包入住,集中供暖",/zufang/41348855.html 朝陽,雙橋,東一時區,4500,65 平米,中樓層/26層,精裝,距離地鐵管莊1214米,1 室 1 廳,西北,管莊 東一時區 精裝一居室 家電齊全 隨時入住看房,"近地鐵,拎包入住,集中供暖",/zufang/41346286.html ...
最後咱們來看貝殼抓取,貝殼是近些年起來的中介平臺,有點類京東,不只有鏈家,自如房源,還有其餘家;除了貝殼,還有其餘不少短租長租平臺,例如小豬短租,蛋殼等;
有時候我常思考一個問題:
負能量:這些網站都是IT開發人員搞得,咱們都是一個行業,爲何要本身坑本身。若是沒有這麼多中介平臺去搶房源,炒房價,價格可能落下來;
正能量:中介商根據市場需求搭建中介平臺,使廣大租客能夠從正規渠道租房,遠離黑中介,給咱們省去不少租房過程當中遇到難題與煩惱,咱們應該感謝這些中介商。
下面咱們看下貝殼網頁面信息:
貝殼房源信息中除了基本信息,還包括房源屬於哪一個中介商,例如:自如,鏈家等;貝殼抓取過程和鏈家也是相似的,具體實如今這裏不作講解,直接看咱們抓取的數據:
中介商,價格,面積,信息,區域,位置,戶型,樓層,附加信息,詳情頁地址 鏈家,14000,84㎡,整租 · 海運倉小區 3室1廳 14000元,東城,東直門,3室1廳1衛,低樓層(7層),"近地鐵,精裝,集中供暖",/zufang/BJ2058598225715675136.html 鏈家,9200,89㎡,整租 · 安定門 安德路 精裝修大兩居 可拎包入住,東城,安定門,2室1廳1衛,高樓層(19層),"近地鐵,精裝",/zufang/BJ2047499309347512320.html 鏈家,6000,61㎡,整租 · 安化南里 1室1廳 6000元,東城,廣渠門,1室1廳1衛,低樓層(16層),"近地鐵,新上,隨時看房",/zufang/BJ2062732570394894336.html 鏈家,3500,14㎡,整租 · 南剪子巷 1室1廳 3500元,東城,東四,1室1廳0衛,低樓層(1層),"近地鐵,新上,隨時看房",/zufang/BJ2064894449783685120.html 鏈家,25000,158㎡,整租 · 東城逸墅南北通透大三居 婚房出租 可看房 傢俱齊全,東城,工體,3室1廳2衛,中樓層(7層),"近地鐵,精裝,集中供暖,雙衛生間,隨時看房",/zufang/BJ2034641117466591232.html 城家精選公寓,11300,43㎡,整租 · 元嘉國際公寓 1室0廳,東城,東直門,1室0廳1衛,未知(10層),"公寓,租房節,七天換租,近地鐵,精裝,集中供暖,免中介費,押一付一,新上",/zufang/BJ2066558104174067712.html 鏈家,28000,207㎡,盛德大廈 4室2廳 28000元,東城,和平里,4室2廳2衛,中樓層(20層),"近地鐵,集中供暖,隨時看房",/zufang/BJ2049715273455910912.html 龍源易家,3500,26㎡,合租 · 海運倉小區 3室1廳,東城,東直門,3室1廳1衛,未知(6層),"限女生,限男生,獨立衛生間,租房節,近地鐵,精裝,獨立陽臺,集中供暖,免中介費,新上",/zufang/BJ2066335711790891008.html ...
房源信息抓取完成後保存到csv文件中,而後對數據進行分析,找到適合本身的那一套。
老貓算了下,三個平臺數據加起來差很少7W套左右(鏈家數據和貝殼有重複,同一個房源可同時掛在不一樣中介商下),全部應該到不了7W套。
老貓使用Python中的matplotlib, pandas, seaborn, pyecharts對數據進行分析。
#pandas導入文件 pathlj = ljinfo.csv' ljdata = pd.read_csv(pathlj) #按區域分組 r = ljdata.groupby('區域') #根據價格統計最大、最小、均值、數量 r.價格.agg(['max', 'min', 'mean', 'count'])
結果以下:
使用柱狀圖描述各區房源數量與均價:
在來分析下鏈家,貝殼與我愛我家各區域房源統計結果:
經過統計結果能夠看到:我愛我家房源比鏈家,貝殼要多,假設房源都是真是的,若是要在朝陽,海淀租房能夠選擇我愛我家。
當前數據中,出租房源良莠不齊,面積價格都不同,不能統一統計,經過箱狀圖看房租價格統計,具體實現以下:
#文件路徑 pathlj = 'ljinfo.csv' #pandas導入 ljdata = pd.read_csv(pathlj) #過濾掉房租價格大於1W的,老貓認爲這輩子也不會租這樣的房 data = ljdata[ljdata.價格 < 10000] plt.figure(figsize=(10,4)) #箱狀圖查看房租價格總體趨勢 sns.boxplot(x='區域',y ='價格', data=data)
輸出結果:
簡單介紹下箱狀圖:箱狀圖使用四分位數表述數據分佈狀況,中間矩形表示25%到75%之間數據分佈,超過上限和下限認爲是異常值;
再來看我愛我家與貝殼統計結果,以下圖:
從圖中能夠看到帝都核心區域房租明顯比郊區高不少,東城最低房源價格都得兩千多,亦莊雖然在五環外,可是由於是開發區,有不少大公司入住,全部房價較高;房源選擇上,我愛我家價格感受比其餘兩個平臺要高。
如今我對北京租房價格有了全新認識,我主要想找70到85平左右小兩居,須要找到各區這個面積範圍內房源及其對應價格,我對鏈家數據進行下面操做:
import re #數據整理,將字符串轉成數字 def func(size): s = re.search(r'\d+', size) if s: return int(s.group()) return pd.np #pandas導入數據 pathlj = 'jinfo.csv' ljdata = pd.read_csv(pathlj) data = ljdata.面積.to_frame() #整理面積數據 r = data.applymap(func) #添加新的列 ljdata['hsize'] = r.面積 #清洗無面積房源 rdata = ljdata.dropna(subset=['hsize']) #整理70~85平米之間房源 rdata = rdata[(rdata.hsize>70) & (rdata.hsize < 85)] #過濾掉價格大於1W的房源 rdata = rdata[rdata.價格<10000] #統計最小值,最大值,均值 rdata.價格.agg(['min', 'max', 'mean'])
輸出結果以下:
min 2500.0 max 9890.0 mean 5997.4
通過分析,老貓感受3000左右能夠租到想要的房子,而後統計各個轄區內房源面積在70~85平之間的價格分佈,結果以下:
核心區域價格確實高,老貓想找大興和亦莊開發區附近房子,價格好像超出老貓預算,我租住房屋面積75,房租3100,房東加800也纔不到4000,根據分析結果看,找4000左右的兩居室感受也沒那麼容易;再找一下大興和亦莊開發區的房子,具體實現以下:
tdata = rdata[rdata.區域.isin(['大興','亦莊開發區'])] #大興與亦莊房子數據 print(len(tdata)) #房源均價,最低,最高值 print(tdata.價格.agg(['mean', 'min', 'max'])) #房源價格小於4000 print(len(tdata[tdata.價格<4000]))
輸出結果以下:
109 mean 4907.889908 min 3100.000000 max 9000.000000 21
找到21套價格小於4000房源,看下房源信息,可能是老舊樓,或者高樓層沒電梯,好容易有合適的,打電話諮詢,已經租出去了;鏈家都已經這樣了,估計我愛我家,貝殼也相似。
思前想後,感受仍是如今房東最好,趕忙給她聯繫續租,如下聊天記錄。
這波漲租潮,對老貓來講就這樣過去了,看着滿屏幕房源信息,我不知道明年房租是否還會瘋長;如今老貓的租房競爭對手不只是衆多北漂,還有實力更爲雄厚的自如、蛋殼等各類中介商,爲了生存,今年必需要更加努力了。
最後打個小廣告,有對爬蟲和數據分析感興趣同窗能夠購買奇貓的專欄《Python爬蟲與數據分析》
另外,若是感受還行能夠關注奇貓的視頻課程或者微職位。