【Python】爬取贝壳网深圳二手房数据

您所在的位置:网站首页 贝壳房产数据 【Python】爬取贝壳网深圳二手房数据

【Python】爬取贝壳网深圳二手房数据

2024-06-18 02:54| 来源: 网络整理| 查看: 265

【Python】爬取贝壳网深圳二手房数据 一,爬取数据

1,爬取目标内容 在这里插入图片描述 在这里插入图片描述 先打开页面https://sz.ke.com/ershoufang/ ,看下页面的结构,分页的列表页,点击就可以跳转到对应的详细页面,有详细的二手房信息。 在这里插入图片描述 主要爬取编号、户型、楼层、朝向、面积、单位面积房价、总价、小区名称、所在区域以及URL。

2,爬起思路 贝壳网二手房都是这种分页的形式,总共100页,每一页的列表有30个二手房详细页链接。两种思路: 第一,用循环的方式,构建下一页URL,访问抓取,直到100页后停止; 第二,直接用xpath定位下一页的标签属性href,取出下一页URL,直至100页,此时下一页的标签属性href是空值,于是停止抓取。 但是,贝壳网底部的分页栏数据是通过js动态加载出来的,所以,直接requests请求的页面,没法用xpath定位下一页的标签,因此,还是采用第一种思路,根据页数循环请求下一页的数据内容。

于是开始写代码,用scrapy框架爬取,写好spider代码,并且使用之前已经做好的cookies池以防被反爬。结果一运行,速度还可以,也正常运行,就是数据有点少,才3000条,但是页面显示总共4万多条房源信息,数据量差得有点多。

如果按照之前的思路就只能爬取3000条房源信息,因为就总共显示100页,一页30条,上限就3000。所以需要换种思路,观察页面,发现可以按区域筛选,比如,罗湖区-百仕达下有686条房源,如果只爬取这个区域的,没超过3000,肯定可以完整地爬取686条,其他区域也是相同的,这样一个一个区域的爬取就基本把整个深圳市的二手房信息都爬取了。 在这里插入图片描述 接下来,就是要解决分页的问题,可以看到每个区域二手房总数都会显示出来,比如罗湖区-百仕达有686条,那么一页显示30条,那就至少有23页,前面22页每页都是30条,第23页只有26条,这要计算出页数后,再构造循环去抓取每一页就行了,其他区域也是相同的做法。

3,代码实现 思路确定后,就代码实现,还是使用scrapy框架爬取,但是在此需要获取所有小区域的URL。先规定,罗湖区这样的大区域为一级区域,其下的区域为二级区域。这样先爬取一级区域URL,再根据一级区域URL爬取二级区域的。

class BeikeInit(object): def __init__(self, city): self.pre_url = city_url.get(city) #城市url def get_ershoufang(self): """ 爬取一级区域url :return:一级区域url列表 """ response = requests.get(self.pre_url) if response.status_code == 200: etree_obj = etree.HTML(response.text) region_lists = etree_obj.xpath('//div[@data-role="ershoufang"]/div/a/@href') region_urls = [self.pre_url+url[11:] for url in region_lists] return region_urls def get_area(self,region_urls): """ 根据一级区域url,爬取其下的二级区域url :param region_urls: 一级区域url列表 :return: 二级区域url列表 """ area_urls =[] for url in region_urls: response = requests.get(url) if response.status_code == 200: etree_obj = etree.HTML(response.text) area_lists = etree_obj.xpath('//div[@data-role="ershoufang"]/div[2]/a/@href') for url in area_lists: area_urls.append(self.pre_url + url[12:]) return area_urls

接下来编写spider代码,最主要是构建初始爬取的url队列,以及页码,页数的计算以及传递,以下是部分代码:

def start_requests(self): # 根据二级区域url,构建爬取队列 for url in self.area_urls: # 请求时,传递初始的参数,url,页码,页数 yield scrapy.Request(url=url,callback=self.parse, meta={'region_url': url, 'curpage': 0, 'pagenum':0}) def parse(self, response): # 获取请求时携带的参数 region_url = response.meta['region_url'] curpage = response.meta['curpage'] pagenum = response.meta['pagenum'] if curpage == 0: # 获取总数 total = response.xpath('//div[@class="resultDes clear"]//span/text()').extract_first().strip() # 设置当前页的页码为1 curpage = 1 # 计算页面数 pagenum = math.ceil(int(total) / 30) house_list = response.xpath('//ul[@class="sellListContent"]//li[@class="clear"]') # 爬取详细页 for i_item in house_list: house_item = KeItem() url = i_item.xpath('.//a/@href').extract_first() house_item['url'] = url # 请求详细页 yield scrapy.Request(url=url, callback=self.parse_detail, meta={'item': house_item}) curpage +=1 # 页码加1 # 判断是否继续爬取下一页 if curpage


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3