今天要分享的教程是爬取各大城市的二手房数据,抛开以前的文章不谈,下面的内容应该足够你实现这篇爬虫。以下是正文:

1. 确定目标

今天我们的目标官网链接是:https://www.lianjia.com/

对应的某个城市的二手房页面应该是:https://sz.lianjia.com/ershoufang/

sz 代表城市深圳的简写,广州对应的是 gz。

ok,前提条件交代清楚了,接下来看看今天要爬取的目标数据

两个页面需要注意,第一个页面是你打开上面那个链接之后显示的列表页面,第二个页面是你点击某个二手房的链接之后跳转的房屋详细数据页面

1.1. 先来说第一个页面

这个页面包括三部分,最上面的搜索部分、中间的列表部分、下面的翻页部分。

上面的搜索部分看似无用,但其实是官方强行设置的一个小操作。

举个最直观的例子:在某个搜索条件下,例如深圳市,对应的清单中有 39053 条记录

而你将页面拉到最下面进行翻页,发现实际只有 100 页可供操作

根据每一页只有 30 条数据的官方设置,你如果不设置搜索条件,只能拿到 3000 条数据

所以,要想获取全部数据,第一个搜索功能就派上用场了。

但是,添加搜索必然会导致整个程序的复杂度直线上升,特别是现在有如此多的搜索条件

综上,最好的解决方式是筛选出 重要且能完美区分的搜索条件,例如:区域+户型+朝向

上述设置的目的是:

通过条件设置之后,通过筛选 xx区 的数据,发现数据大于 3000条,则利用户型是 x居室 的进行二次筛选,如果发现仍大于 3000条,再次通过 朝x 进行三次筛选

基本上到了第三次筛选之后,数据会在 3000以内,对应的可以全部拿到。

其他筛选条件应该也能实现同样的效果,这个自己设定即可

对了,筛选条件除了每个城市的区域没法固定外,居室和朝向都是固定的

通过F12查看源码可以看到居室和朝向对应的系统定位如下:

对应的,在代码中也就可以将其进行映射:

# 户型:一室、二室、三室、四室、五室、五室+
self.rooms_number = ['l1', 'l2', 'l3', 'l4', 'l5', 'l6']
# 朝向:朝东+朝南+朝西+朝北+南北
self.orientation = ['f1', 'f2', 'f3', 'f4', 'f5']

再来看中间的列表部分

列表部分有 3 个信息需要注意,如下图:

分别是:小区名+区域、其他标签、价格

如果这些字段信息已经可以满足你的数据需求,那对应的爬虫只需要获取这个页面的数据,不需要分析第二个页面,相对来说比较简单

如果你需要更详细的二手房指标,例如:挂牌时间、抵押情况、产权等,以及该房子的经纬度数据,那你需要分析第二个页面

最后是下面的翻页部分

翻页部分原理比较简单,通过多次点击下一页按钮,观察新页面的 url 链接就能发现规律

例如:https://sz.lianjia.com/ershoufang/luohuqu/pg2l1/ 中的 pg2 对应的是第二页的数据

而 l1 在前面我们已经知道是一居室的意思,所以对应的翻页页面的 url 规则应该是:主页+区域+pg页码+居室

在翻页遍历的过程中只需要更改 pg页码 即可。

1.2. 再来说第二个页面

第二个页面是通过第一个页面点击跳转的,我举个例子:

通过点击图中上面的标签,会跳转到下面链接对应的新页面

链接中后面的数字编号对应的是该二手房的编码id。

第二个页面有三个部分,分别是:价格+位置、基本信息+交易信息、地图

价格+位置部分数据如下图:

从价格部分可以获取到:参考总价、单价

从所在区域可以获取到:小区名称、大区域+小区域

基本信息+交易信息数据如下图:

因为这张图上的数据比较全,所以我并没有解析上张图的其他数据

这张图上的基本属性和交易属性都可以拿下来作为房屋字段

最后是地图部分的数据

这部分数据比较多,例如:最近的地铁站点、公交站点等

以及在地图插件中隐藏的房屋经纬度数据

因为以前的文章专门爬过地铁站点数据,所以我在这里只拿了经纬度数据

2. 流程设计

目标已经明确,总结一下上面我们需要注意的地方,大概如下:

首先,判断该城市的总数据是否超过 3000 条,若超过则需要设置筛选条件。先通过区域进行筛选,其次通过居室进行筛选,最后通过朝向进行筛选

上述筛选过程中任一过程若存在数据小于 3000条,则停止往下筛选。

其次,在确定筛选条件之后,通过解析每一页的二手房链接跳转到详情页。翻页操作只需要根据页码重新构造 url 即可

最后,对二手房详情页进行解析,保存数据到本地文件中。

为了方便对整个流程进行复现,我做了一个流程图,如下:

3. 主要代码复现

通过上面的流程图,可以完成整个爬虫的代码复现

因为涉及的代码较多,这里只贴核心代码,完整的代码可以在文末获取

首先是获取当前条件下的房屋数据个数:

def get_house_count(self):"""获取当前筛选条件下的房屋数据个数"""# 爬取区域起始页面的数据response = requests.get(url=self.current_url, headers=self.headers)# 通过 BeautifulSoup 进行页面解析soup = BeautifulSoup(response.text, 'html.parser')# 获取数据总条数count = soup.find('h2', class_='total fl').find('span').string.lstrip()return soup, count

其次是主页面的设计:

判断是否超过3000,若超过则进行第二级筛选,若未超过则直接获取数据

def get_main_page(self):# 获取当前筛选条件下数据总条数soup, count_main = self.get_house_count()# 如果当前当前筛选条件下的数据个数大于最大可查询个数,则设置第一次查询条件if int(count_main) > self.page_size*self.max_pages:# 获取当前地市的所有行政区域,当做第一个查询条件soup_uls = soup.find('div', attrs={'data-role': 'ershoufang'}).div.find_all('a')self.area = self.get_area_list(soup_uls)# 遍历行政区域,重新生成筛选条件for area in self.area:self.get_area_page(area)else:# 直接获取数据self.get_pages(int(count_main), '', '', '')# 保存数据到本地self.data_to_csv()

对应的在确定区域的条件下,继续判断并筛选居室

在确定区域和居室的条件下,继续判断并筛选朝向

在确定区域、居室和朝向的条件下,直接获取 前3000条 数据

可以看到上面的流程十分类似,对应的代码大家注意看源码就行。

如果在三级筛选下仍存在超过3000条数据,照葫芦画瓢就行

在代码执行的过程中,建议每获取到 10条 数据保存一次,避免中途程序出错而前功尽弃

对应的代码可以参考如下:

'''超过10条数据,保存到本地'''
if len(self.data_info) >= 10:self.data_to_csv()

在保存到本地 csv 的时候,建议采用追加的方式进行保存

也就是在 data_to_csv 函数中这样写:

def data_to_csv(self):"""保存/追加数据到本地@return:"""df_data = pd.DataFrame(self.data_info)if os.path.exists(self.save_file_path) and os.path.getsize(self.save_file_path):# 追加写入文件df_data.to_csv(self.save_file_path, mode='a', encoding='utf-8', header=False, index=False)else:# 写入文件,带表头df_data.to_csv(self.save_file_path, mode='a', encoding='utf-8', index=False)# 清空当前数据集self.data_info = []

另外,考虑到大多时候需要运行好几次程序才能获取到所有数据

在每次运行程序的时候先统计已经爬到的房屋数据,跳过已经爬到的数据

对应的代码可以这样写:

# 所有已经保存的房屋 id,用来验证去重
self.house_id = self.get_exists_house_id()def get_exists_house_id(self):"""通过已经爬取到的房屋信息,并获取房屋id@return:"""if os.path.exists(self.save_file_path):df_data = pd.read_csv(self.save_file_path, encoding='utf-8', )df_data['house_id'] = df_data['house_id'].astype(str)return df_data['house_id'].to_list()else:return []

最后,在主函数中只需要设置城市名称和数据保存路径即可

代码如下:

if __name__ == '__main__':city_number = 'sz'city_name = '深圳'url = 'https://{0}.lianjia.com/ershoufang/'.format(city_number)page_size = 30save_file_path = '二手房数据-sz.csv'house = House(city_name, url, page_size, save_file_path)house.get_main_page()

完整的代码可以在文末获取

4. 程序运行截图

如果是第一次运行程序,设置好相关参数后,运行截图如下:

如果之前有运行过程序,中途退出了。

再次运行时无需设置参数,直接运行即可,截图如下:

最终爬取到的部分数据如下:

5. 写在最后的话

整体来说,虽然流程的设计比较繁琐,但是仍然是很基础的一篇内容

与本文相关的爬虫参数设置、简单爬虫伪装,网页解析都可以在以前的文章中找到,在此不一一提及

另外,建议大家在运行的过程中,适当的设置程序休眠,理性爬虫。

END -

本文为转载分享&推荐阅读,若侵权请联系后台删除
-------------------------------------
长按识别下方二维码,并关注公众号1.回复“PY”领取1GB Python数据分析资料2.回复“BG”领取3GB 名企数据分析报告

Python爬取城市二手房数据相关推荐

  1. Python 爬取北京二手房数据,分析北漂族买得起房吗?(附完整源码)

    来源:CSDN 本文约3500字,建议阅读9分钟. 本文根据Python爬取了赶集网北京二手房数据,R对爬取的二手房房价做线性回归分析,适合刚刚接触Python&R的同学们学习参考. 房价高是 ...

  2. Python爬取城市天气数据,并作数据可视化

    1.爬取广惠河深2022-2024年的天气数据 import requests # 发送请求要用的模块 需要额外安装的 import parsel import csvf = open('广-惠-河- ...

  3. 爬取北京二手房数据信息(python)

    数据爬取 爬取北京二手房数据信息python代码: # coding : utf-8from requests import get from bs4 import BeautifulSoup as ...

  4. python 爬取拉钩网数据

    python 爬取拉钩网数据 完整代码下载:https://github.com/tanjunchen/SpiderProject/blob/master/lagou/LaGouSpider.py # ...

  5. 利用python爬取城市公交站点

    利用python爬取城市公交站点 页面分析 https://guiyang.8684.cn/line1 爬虫 我们利用requests请求,利用BeautifulSoup来解析,获取我们的站点数据.得 ...

  6. Python应用实战-Python爬取4000+股票数据,并用plotly绘制了树状热力图(treemap)

    目录: 1. 准备工作 2. 开始绘图 2.1. 简单的例子 2.2. px.treemap常用参数介绍 2.3. color_continuous_scale参数介绍 2.4. 大A股市树状热力图来 ...

  7. python爬去朋友圈_利用Python爬取朋友圈数据,爬到你开始怀疑人生

    人生最难的事是自我认知,用Python爬取朋友圈数据,让我们重新审视自己,审视我们周围的圈子. 文:朱元禄(@数据分析-jacky) 哲学的两大问题:1.我是谁?2.我们从哪里来? 本文 jacky试 ...

  8. python 爬取拉钩数据

    Python通过Request库爬取拉钩数据 爬取方法 数据页面 建表存储职位信息 解析页面核心代码 完整代码 结果展示 爬取方法 采用python爬取拉钩数据,有很多方法可以爬取,我采用的是通过Re ...

  9. 利用Python爬取国家水稻数据中心的品种数据

    利用Python爬取国家水稻数据中心的品种数据 一.页面获取 python可以进行对网页的访问,主要用到requests,beautifulsoup4包. 首先新建一个page的py文件,用来获取页面 ...

  10. 利用Python爬取朋友圈数据,爬到你开始怀疑人生

    人生最难的事是自我认知,用Python爬取朋友圈数据,让我们重新审视自己,审视我们周围的圈子. 文:朱元禄(@数据分析-jacky) 哲学的两大问题:1.我是谁?2.我们从哪里来? 本文 jacky试 ...

最新文章

  1. ifstream java_C ifstream将读取一些值然后停止
  2. OpenCV与FLANN的功能匹配
  3. QT的QOpenGLFunctions类的使用
  4. Python的seaborn库(图比较炫)
  5. 如何处理Docker错误消息:please add——insecure-registry 1
  6. junit rule_使用JUnit的ExpectedException和@Rule测试自定义异常
  7. java opencv4.5 人脸对比_2020大数据Java面试总结(未完待续)
  8. shiro访问html没有验证码,Shiro在web应用中实现验证码、回显登录失败信息
  9. 如何使用dtls协议抵御重放攻击
  10. C语言求斐波那契数列前10项
  11. hexo和github pages的关系
  12. python3安装pymysql_ubuntu16.04 python3安装pymysql错误
  13. Hibernate【缓存】知识要点
  14. 《数据库原理与应用》作业(1-0.5)
  15. 2020年度中职组“网络空间安全”赛项xx市竞赛任务书
  16. Servlet-JSP-课堂笔记
  17. 如何用golang远程控制浏览器
  18. 红米4刷linux,极客精神,国外大神将红米Note 7刷上了Ubuntu
  19. No space left on device: mod_rewrite: could not create rewrite_log_lock
  20. python下载m3u8视频_使用python 下载m3u8格式视频,并使用ffmpeg 合成视频

热门文章

  1. DOE全因子实验设计报告
  2. ios 渐变透明背景_2019 - 渐变梯度
  3. 2018网易编程射击游戏
  4. vue 中国省市区级联数据下拉工具
  5. (转自头条新闻)黄金搭档:自然语言处理(NLP)+ 知识图谱
  6. 拼音表大全图_阿波罗 STM32F767 开发板资料连载第五十九章 T9 拼音输入法实验
  7. 蓝牙双模音频模块 BT401蓝牙BLE应用笔记
  8. VsCode建立工程
  9. 计算机文件夹中看不到桌面图标,电脑文件夹内不显示图标
  10. elementui二维表动态渲染