一、说在前面
受人所托,爬取链家上地图找房的数据:/ditu/。
上面有按区域划分的二手房均价和在售套数,我们的任务就是抓下这些数据。
二、开干
2.1失败一次
老样子,Chrome 按下F12打开Chrome DevTools中的Network标签查看请求过程,像这种需要更新的数据大概率是通过后台接口请求返回的,遗憾的是在XHR下并没有找到接口,小泄气。
继续找,在JS下发现了一个可疑的请求:/map/search/ershoufang/
嘻嘻,就是你了。然后就是熟悉的模拟请求过程了,把Headers、Query String Parameters都带上,一通操作猛如虎之后:
什么鬼啊,一个简单的GET请求,模拟了所有请求头和参数,甚至在浏览器里头都无法再次请求成功。应该是链家做了什么限制,如果有大牛不小心路过此篇能给予一些指导那是再好不过了。感激不尽,感激不尽。
2.2重新起航
此路不通,只好寻找别的办法。链家的地图找房功能其实找的是二手房,于是我进入二手房的房价页面,发现了一个类似的数据展示页面。/fangjia/
这个页面就很有意思了,直接摆了一个明晃晃的接口。 Request URL:/fangjia/priceMap/
数据也十分地明晃晃:
可惜的是这个接口并不带套数这个数据,不管了。先爬下来再说。
2.3代码简单解读
import requests
from bs4 import BeautifulSoup
from datetime import datetime
def get_city_list():
city_list = {}
city_from_url = '/city/'
mhtml = (city_from_url)
mobj = BeautifulSoup(,'lxml')
city_block = .find_all('div',{'class':'block city_block'})
for cb in city_block:
for cba in cb.find_all('a'):
city_list[('href')] = cba.get_text()
return city_list
if __name__ == '__main__':
cityd = get_city_list()
f = open('houing_price_bycity.csv','w',encoding = 'utf-8')
for citycode,city in ():
url = 'https://{}./fangjia/priceMap/'.format(citycode[1:-1])
try:
r = (url)
if r.status_code == 200:
res = ()
else:
continue
except:
continue
for k,v in ():
if isinstance(v,(int,float)):
pass
else:
cont = ','.join([city,v['name'],str(v['transPrice']),().strftime("%Y-%m-%d %H:%M:%S")])
cont = cont + '\n'
(cont)
()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
先是从一个链家移动端的页面,抓取所有的城市列表和它们在链家内部的代号。用这个代号去替换请求中的城市部分,以此实现循环所有城市列表抓下所有城市的分区域房价信息。实际应用中发现不是所有城市都有这个地图找房的接口,主要是一些大城市才有。
因为是自用的小爬虫,一些报错处理也十分简单粗暴,请求过程也没有设定重试模块,也没有限制访问速度应对可能存在的链家反爬机制(结果来看,这个接口大概率没有做反爬),结果也直接写进了当前目录的CSV文档。显然存在许多可以优化的点。whatever,自己用用的小爬虫就不讲究这么多了啦。
最后爬下来的结果长这样:
结束
本文到此就结束了,不过细心的小朋友可能会发现好像漏了什么。
没错,一开始链家地图找房的功能里是有房价和在售套数两个数据的,现在我们只获取了其中一个。因为套数这个数据我们在接口里没有找到,不过我仍然找到了数据获取的地方。
在链家-二手房-在售页面,通过按区域搜索可以看到这个数据直接展示在页面上:
这个数据是直接写在网页html代码里的,按区域抓下来与之前的房价数据匹配起来即可。我们也由此可知,这个数据更新地不会很勤快,这一步就留给有需要的人去做吧。方法已经给到,实现自然不是什么难事。
此篇正式终结,88。