爬取了上萬條租房數據,你還要不要北漂?

爬取了上萬條租房數據,你還要不要北漂?

8 月初,有網友在“水木論壇”發帖控訴長租公寓加價搶房引起關注。據說,一名業主打算出租自己位於天通苑的三居室,預期租金 7500 元/月,結果被二方中介互相抬價,硬生生抬到了 10800 元。

過去一個月,全國熱點城市的房租如脫韁野馬。一線的房租同比漲了近 20%。一夜醒來,無產青年連一塊立錐之地都懸了。

從 2018 下半年開始,租金海嘯般洶洶來襲,資本狂歡,官方默然,房東糾結,租客尖叫。

這不是一方的過錯,而更像是一場全社會的“集體謀殺作品”。最令人不安的是,過去房地產的那套玩法和上漲邏輯,今天正在轉移到房租上。

房租暴漲的不只是北京。有數據顯示,7 月份北京、上海、廣州、深圳、天津、武漢、重慶、南京、杭州和成都十大城市租金環比均有所上漲。

其中北京、上海、深圳的租金漲幅最猛,北京 7 月份房租同比上漲 3.1%,有小區甚至漲幅超過 30%。

爬取了上萬條租房數據,你還要不要北漂?

圖自“21世紀經濟報道”《最新房租數據出爐,你一個月要交多少錢?(附房租地圖)》一文

接下來,本文使用 Python 大法通過獲取某網數萬條北京租房數據,給大家說說真實的房租情況。

還是老規矩,老套路(是不是有股熟悉的味道),常用的三部曲:數據獲取、數據清洗預覽、數據分析可視化,與你一起探究最近房租的狀況。

數據獲取

今日就以目前市場佔有率最高的房屋中介公司為目標,來獲取北京、上海兩大城市的租房信息。(目標鏈接:https://bj.lianjia.com/zufang/)

爬取了上萬條租房數據,你還要不要北漂?

整體思路是:

  • 先爬取每個區域的 url 和名稱,跟主 url 拼接成一個完整的 url,循環 url 列表,依次爬取每個區域的租房信息。
  • 在爬每個區域的租房信息時,找到最大的頁碼,遍歷頁碼,依次爬取每一頁的二手房信息。

post 代碼之前,先簡單講一下這裡用到的幾個爬蟲 Python 包:

  • requests:是用來請求對鏈家網進行訪問的包。
  • lxml:解析網頁,用 Xpath 表達式與正則表達式一起來獲取網頁信息,相比 bs4 速度更快。

詳細代碼如下:

  1. import requests
  2. import time
  3. import re
  4. from lxml import etree
  5. # 獲取某市區域的所有鏈接
  6. def get_areas(url):
  7. print('start grabing areas')
  8. headers = {
  9. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'}
  10. resposne = requests.get(url, headers=headers)
  11. content = etree.HTML(resposne.text)
  12. areas = content.xpath("//dd[@data-index = '0']//div[@class='option-list']/a/text()")
  13. areas_link = content.xpath("//dd[@data-index = '0']//div[@class='option-list']/a/@href")
  14. for i in range(1,len(areas)):
  15. area = areas[i]
  16. area_link = areas_link[i]
  17. link = 'https://bj.lianjia.com' + area_link
  18. print("開始抓取頁面")
  19. get_pages(area, link)
  20. #通過獲取某一區域的頁數,來拼接某一頁的鏈接
  21. def get_pages(area,area_link):
  22. headers = {
  23. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'}
  24. resposne = requests.get(area_link, headers=headers)
  25. pages = int
    (re.findall("page-data=\'{"totalPage":(\d+),"curPage"", resposne.text)[0])
  26. print("這個區域有" + str(pages) + "頁")
  27. for page in range(1,pages+1):
  28. url = 'https://bj.lianjia.com/zufang/dongcheng/pg' + str(page)
  29. print("開始抓取" + str(page) +"的信息")
  30. get_house_info(area,url)
  31. #獲取某一區域某一頁的詳細房租信息
  32. def get_house_info(area, url):
  33. headers = {
  34. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'}
  35. time.sleep(2)
  36. try:
  37. resposne = requests.get(url, headers=headers)
  38. content = etree.HTML(resposne.text)
  39. info=[]
  40. for i in range(30):
  41. title = content.xpath("//div[@class='where']/a/span/text()")[i]
  42. room_type = content.xpath("//div[@class='where']/span[1]/span/text()")[i]
  43. square = re.findall("(\d+)",content.xpath("//div[@class='where']/span[2]/text()")[i])[0]
  44. position = content.xpath("//div[@class='where']/span[3]/text()")[i].replace(" ", "")
  45. try:
  46. detail_place = re.findall("([\\u4E00-\\u9FA5]+)租房", content.xpath("//div[@class='other']/div/a/text()")[i])[0]
  47. except Exception as e:
  48. detail_place = ""
  49. floor =re.findall("([\\u4E00-\\u9FA5]+)\(", content.xpath("//div[@class='other']/div/text()[1]")[i])[0]
  50. total_floor = re.findall("(\d+)",content.xpath("//div[@class='other']/div/text()[1]")[i])[0]
  51. try:
  52. house_year = re.findall("(\d+)",content.xpath("//div[@class='other']/div/text()[2]")[i])[0]
  53. except Exception as e:
  54. house_year = ""
  55. price = content.xpath("//div[@class='col-3']/div/span/text()")[i]
  56. with open('鏈家北京租房.txt','a',encoding='utf-8') as f:
  57. f.write(area + ',' + title + ',' + room_type + ',' + square + ',' +position+
  58. ','+ detail_place+','+floor+','+total_floor+','+price+','+house_year+'\n')
  59. print('writing work has done!continue the next page')
  60. except
    Exception as e:
  61. print( 'ooops! connecting error, retrying.....')
  62. time.sleep(20)
  63. return get_house_info(area, url)
  64. def main():
  65. print('start!')
  66. url = 'https://bj.lianjia.com/zufang'
  67. get_areas(url)
  68. if __name__ == '__main__':
  69. main()

數據清洗預覽

爬取了上萬條租房數據,你還要不要北漂?

爬取數據共 14038 條,有 10 個維度,由上圖可看出北京房源均價為 9590 元/月,中位數為 7000。

一半的房源價格在 7000 以下,所有房源的價格區間為 [1000,250000],價格極差過大。

數據分析可視化

四維度-北京房租均價

接下來,我將北京各區域、各路段、各樓盤房屋數量、均價分佈放在同一張圖上,更直觀地來看待房租。

爬取了上萬條租房數據,你還要不要北漂?

從圖中可看出,最近,北京市各區域的房租均在 6000 元/月以上,其中最高區域為東城,均價達 12463 元/月。

不過,由於房源信息過多過雜,房屋位置、面積、樓層、朝向等對價格均有較大影響,因此,價格這個維度需要進一步分析。

爬取了上萬條租房數據,你還要不要北漂?

由上圖可得,各路段的均價基本都在 6000 元以上,其中海淀北部新區的房源數最多,但均價最低,為 3308 元/月。

這或許與海淀北部生態科技新區作為高新技術產業的承載區、原始創新策源地的研發基地,以及科技園集聚區,目前已入駐華為、聯想、百度、騰訊、IBM、Oracle 等近 2000 家國內外知名的科技創新型企業有關。

另一方面,海淀紫竹橋的房價竟一起沖天,其附近以博物館、體育場館為特色,交通便利,配套設施完善,均價較高也是情理之中。

爬取了上萬條租房數據,你還要不要北漂?

可以看出,不同樓盤的均價浮動很大,但都在 6000 元/月以上,最高的甚至達到 17516 /月。

由於每個樓盤戶型差別較大,地理位置也較為分散,因此均價波動很大。每個樓盤具體情況還需具體分析。

附詳情代碼:

  1. #北京路段_房屋均價分佈圖
  2. detail_place = df.groupby(['detail_place'])
  3. house_com = detail_place['price'].agg(['mean','count'])
  4. house_com.reset_index(inplace=True)
  5. detail_place_main = house_com.sort_values('count',ascending=False)[0:20]
  6. attr = detail_place_main['detail_place']
  7. v1 = detail_place_main['count']
  8. v2 = detail_place_main['mean']
  9. line = Line("北京主要路段房租均價")
  10. line.add("路段",attr,v2,is_stack=True
    ,xaxis_rotate=30,yaxix_min=4.2,
  11. mark_point=['min','max'],xaxis_interval=0,line_color='lightblue',
  12. line_width=4,mark_point_textcolor='black',mark_point_color='lightblue',
  13. is_splitline_show=False)
  14. bar = Bar("北京主要路段房屋數量")
  15. bar.add("路段",attr,v1,is_stack=True,xaxis_rotate=30,yaxix_min=4.2,
  16. xaxis_interval=0,is_splitline_show=False)
  17. overlap = Overlap()
  18. overlap.add(bar)
  19. overlap.add(line,yaxis_index=1,is_add_yaxis=True)
  20. overlap.render('北京路段_房屋均價分佈圖.html')
爬取了上萬條租房數據,你還要不要北漂?

由上圖可以看出,均價在 8000-10000 之間的房屋數量最多,同時 1500-2000 這個價位之間房屋數少的可憐。

據北京市統計局的數據,2017 年全市居民月人均可支配收入為 4769 元。另據 58 同城和趕集網發佈的報告,2017 年北京人均月租金為 2795 元。

北京租房者的房租收入比,驚人地接近 60%。很多人一半的收入,都花在了租房上,人生就這樣被鎖定在貧困線上。

統計數據也表明,北京租房人群收入整體偏低。47% 的租房人,年薪在 10 萬以下。

在北京,能夠負擔得起每月 5000 元左右房租的群體,就算得上是中高收入人群。

就這樣,第一批 90 後扛過了離婚、禿頭、出家和生育,終於還是倒在了房租面前。

附詳情代碼:

  1. #房源價格區間分佈圖
  2. price_info = df[['area', 'price']]
  3. #對價格分區
  4. bins = [0,1000,1500,2000,2500,3000,4000,5000,6000,8000,10000]
  5. level = ['0-1000','1000-1500', '1500-2000', '2000-3000', '3000-4000', '4000-5000', '5000-6000', '6000-8000', '8000-1000','10000以上']
  6. price_stage = pd.cut(price_info['price'], bins = bins,labels = level).value_counts().sort_index()
  7. attr = price_stage.index
  8. v1 = price_stage.values
  9. bar = Bar("價格區間&房源數量分佈")
  10. bar.add("",attr,v1,is_stack=True,xaxis_rotate=30,yaxix_min=4.2,
  11. xaxis_interval=0,is_splitline_show=False)
  12. overlap = Overlap()
  13. overlap.add(bar)
  14. overlap.render('價格區間&房源數量分佈.html')

面積&租金分佈呈階梯性

爬取了上萬條租房數據,你還要不要北漂?

上圖可以看出,80% 的房源面積集中在 0-90 平方米之間,也符合租客單租與合租情況,大面積的房屋很少。

爬取了上萬條租房數據,你還要不要北漂?

面積&租金分佈呈階梯性,比較符合常理。租房主力軍就是上班族了,一般對房子面積要求較低,基本集中在 30 平。

附詳情代碼:

  1. #房屋面積分佈
  2. bins =[0,30,60,90,120,150,200,300,400,700]
  3. level = ['0-30', '30-60', '60-90', '90-120', '120-150', '150-200', '200-300','300-400','400+']
  4. df['square_level'] = pd.cut(df['square'],bins = bins,labels = level)
  5. df_digit= df[['area', 'room_type', 'square', 'position', 'total_floor', 'floor', 'house_year', 'price', 'square_level']]
  6. s = df_digit['square_level'].value_counts()
  7. attr = s.index
  8. v1 = s.values
  9. pie = Pie("房屋面積分佈",title_pos='center')
  10. pie.add(
  11. "",
  12. attr,
  13. v1,
  14. radius=[40, 75],
  15. label_text_color=None,
  16. is_label_show=True,
  17. legend_orient="vertical",
  18. legend_pos="left",
  19. )
  20. overlap = Overlap()
  21. overlap.add(pie)
  22. overlap.render('房屋面積分佈.html')
  23. #房屋面積&價位分佈
  24. bins =[0,30,60,90,120,150,200,300,400,700]
  25. level = ['0-30', '30-60', '60-90', '90-120', '120-150', '150-200', '200-300','300-400','400+']
  26. df['square_level'] = pd.cut(df['square'],bins = bins,labels = level)
  27. df_digit= df[['area', 'room_type', 'square', 'position', 'total_floor', 'floor', 'house_year', 'price', 'square_level']]
  28. square = df_digit[['square_level','price']]
  29. prices = square.groupby('square_level').mean().reset_index()
  30. amount = square.groupby('square_level').count().reset_index()
  31. attr = prices['square_level']
  32. v1 = prices['price']
  33. pie = Bar("房屋面積&價位分佈布")
  34. pie.add("", attr, v1, is_label_show=True)
  35. pie.render()
  36. bar = Bar("房屋面積&價位分佈")
  37. bar.add("",attr,v1,is_stack=True,xaxis_rotate=30,yaxix_min=4.2,
  38. xaxis_interval=0,is_splitline_show=False)
  39. overlap = Overlap()
  40. overlap.add(bar)
  41. overlap.render('房屋面積&價位分佈.html')

大多數房屋年齡在 10 年以上

爬取了上萬條租房數據,你還要不要北漂?

由上圖看出,房屋年齡大多集中在 10-20 年、25 年以上,而 5 年以下的不到 2%;不過,別看這些都是老房子,最近房租變得這麼猖狂?原因其中之一就是資本圈地。

爬取了上萬條租房數據,你還要不要北漂?

這條網貼立馬點燃了大眾的情緒:“好啊,原來是這些長租平臺燒錢圈地,一心只想要壟斷市場房源,哄抬租金,企圖賺取暴利差價!”

後記

拿自如舉例,表面上看跟中介公司沒啥兩樣,收了各種散盤,然後集中裝修、出租、管理,因為運營成本和住房質量提高,房租肯定有所上漲。

但更關鍵的事情在背後。自如把項目打包起來搞起了資產證券化,以租金收益權為基礎資產做擔保,投放到金融市場上發行國內首單租房市場消費分期類 ABS,讓各路資金來認購,每年給大家搞點分紅。

大量資本都在賭租房這個風口,而前期誰的規模越大、資源越多,以後的定價權就越大,利潤空間就越不可想象。

這次一共從鏈家網上爬取 14038 條數據,而那就是大概一週前,8 月 17 日北京住建委約談了幾家中介公司。

最終的結果是自如、相寓和蛋殼承諾將拿出 12 萬間房子投入市場其中,自如將拿出 8 萬間(鏈家、自如、貝殼找房,他們的實際控制人是同一個人--鏈家老闆左暉)。

爬取了上萬條租房數據,你還要不要北漂?

也就是說,平常的時候,鏈家網+自如一共在網上待租的也就是 1 萬多套房子,但是一被約談他們就一口氣拿出了 8 萬套房子增援??怎麼增?繼續收房,讓房源更加供不應求?

昨天買不起房,今天租不起房,如果連這樣的生活也要因為市場的不規範而被逼迫、被奪走,真的會讓人對一個城市失去希望。


分享到:


相關文章: