【Python_requests学习笔记(二)】基于requests和lxml模块,爬取链家房产数据

2024-01-23 08:40

本文主要是介绍【Python_requests学习笔记(二)】基于requests和lxml模块,爬取链家房产数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于requests和lxml模块,爬取链家房产数据

前言

此篇文章中介绍基于requests,lxml模块和Xpath选择器,爬取链家房产数据的案例。

正文

1、需求梳理

抓取链家二手房网站中的房源信息,如房源名称、地址、户型、面积、方位、是否精装、楼层、年代、类型、总价。

2、爬虫思路

  1. 确认所抓数据在响应内容中是否存在
    所抓取的内容在响应内容中存在在这里插入图片描述
  2. 分析url地址规律
    第一页:https://qd.lianjia.com/ershoufang/pg
    第二页:https://qd.lianjia.com/ershoufang/pg2/
    第三页:https://qd.lianjia.com/ershoufang/pg3/

    第N页:https://qd.lianjia.com/ershoufang/pgn/
    url地址:https://qd.lianjia.com/ershoufang/pg{n}/
  3. 写xpath表达式
    在这里插入图片描述
    从上图li标签中可以看到 检查中存在两个属性:
    clear LOGCLICKDATA
    clear LOGVIEWDATA LOGCLICKDATA
    所以需要通过检查网页源代码中查看,究竟以哪一个为准:
    在这里插入图片描述
    以此确定基准xpath://li[@class='clear LOGVIEWDATA LOGCLICKDATA']
    for循环依次遍历后得到详细信息:
    名称:.//div[@class='positionInfo']/a[1]/text()
    区域:.//div[@class='positionInfo']/a[2]/text()
    详细信息:.//div[@class='houseInfo']/text()
    总价:.//div[@class='totalPrice']/span/text()
    单价:.//div[@class='unitPrice']/span/text()
  4. 编写程序框架、完善程序

注意:

1、在写xpath表达式时一切以响应内容为主
2、页面HTML为最终渲染完之后的,和响应内容的HTML不一定相同
3、防止页面中出现特殊数据,所以在取下标索引前需要先进行判断
4、如果出现特殊页面迟迟不给响应,则设立重试机制

3、程序实现

  1. 初始化函数
    def __init__(self):self.url = 'https://qd.lianjia.com/ershoufang/pg{}/'  # url地址self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'}  # 重构请求头self.i = 0  # 初始化计数
  1. 获取响应内容函数
    def get_html(self, url):"""function:  获取响应内容函数in:  url:传入的url地址out:  Nonereturn:  int >0 okothers:  Get Response Content Function"""for i in range(3):  # 如果有异常,尝试三次# noinspection PyBroadExceptiontry:html = requests.get(url=url, headers=self.headers, timeout=3).text  # 设置3秒钟的超时时间self.parse_html(html)  # 调用 xpath提取数据函数self.i += 1  # 爬取成功,计数+1print("第{}页爬取成功!".format(self.i))  # 打印break  # 跳出except Exception as e:print("Retry......")  # 捕捉异常
  1. xpath提取数据函数
    def parse_html(self, html):"""function:  xpath提取数据函数in:  html:响应内容out:  Nonereturn:  Noneothers:  Extract Data By Xpath Function"""p = etree.HTML(html)  # 创造解析对象li_list = p.xpath("//li[@class='clear LOGVIEWDATA LOGCLICKDATA']")  # 解析对象调用xpathitem = {}  # 定义一个空字典for li in li_list:  # 遍历 解析对象调用xpath后 得到的数据name_list = li.xpath(".//div[@class='positionInfo']/a[1]/text()")item["名称"] = name_list[0].strip() if name_list else None  # 判断得到的名称列表是否为空address_list = li.xpath(".//div[@class='positionInfo']/a[2]/text()")item["地址"] = address_list[0].strip() if name_list else None  # 判断得到的地址列表是否为空info_li = li.xpath(".//div[@class='houseInfo']/text()")if info_li:  # 判断房源信息是否为空info_li = info_li[0].split("|")  # 用"|"分割if len(info_li) == 7:  # 长度=7item["户型"] = info_li[0].strip()item["面积"] = info_li[1].strip()item["朝向"] = info_li[2].strip()item["装修"] = info_li[3].strip()item["楼层"] = info_li[4].strip()item["年限"] = info_li[5].strip()item["种类"] = info_li[6].strip()else:if len(info_li) == 6:  # 长度=6item["户型"] = info_li[0].strip()item["面积"] = info_li[1].strip()item["朝向"] = info_li[2].strip()item["装修"] = info_li[3].strip()item["楼层"] = info_li[4].strip()item["种类"] = info_li[5].strip()else:if len(info_li) == 8:  # 长度=8item["户型"] = info_li[0].strip()item["面积"] = info_li[1].strip()item["朝向"] = info_li[2].strip()item["装修"] = info_li[3].strip()item["楼层"] = info_li[4].strip()item["年限"] = info_li[5].strip()item["种类"] = info_li[6].strip()item["种类"] += info_li[7].strip()else:item["户型"] = item["面积"] = item["朝向"] = item["装修"] = item["楼层"] = item["年限"] = item["种类"] = Noneelse:item["户型"] = item["面积"] = item["朝向"] = item["装修"] = item["楼层"] = item["年限"] = item["种类"] = Nonetotal_list = li.xpath(".//div[@class='totalPrice totalPrice2']/span/text()")item["总价"] = total_list[0].strip() if total_list else None  # 判断得到的总价列表是否为空unit_list = li.xpath(".//div[@class='unitPrice']/span/text()")item["单价"] = unit_list[0].strip() if unit_list else None  # 判断得到的单价列表是否为空print(item)  # 打印信息
  1. 程序入口函数
    def run(self):"""function:  程序入口函数in:  Noneout:  Nonereturn:  Noneothers:  Program Entry Function"""for pg in range(1, 6):  # 爬取1-5页url = self.url.format(pg)  # 拼接url地址self.get_html(url)  # 调用 获取响应内容函数time.sleep(random.randint(1, 2))  # 1-2s延时

4、完整代码

import time
import random
import requests
from lxml import etreeclass LianjiaSpider:"""链家二手房数据抓取"""def __init__(self):self.url = 'https://qd.lianjia.com/ershoufang/pg{}/'  # url地址self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'}  # 重构请求头self.i = 0  # 初始化计数def get_html(self, url):"""function:  获取响应内容函数in:  url:传入的url地址out:  Nonereturn:  int >0 okothers:  Get Response Content Function"""for i in range(3):  # 如果有异常,尝试三次# noinspection PyBroadExceptiontry:html = requests.get(url=url, headers=self.headers, timeout=3).text  # 设置3秒钟的超时时间self.parse_html(html)  # 调用 xpath提取数据函数self.i += 1  # 爬取成功,计数+1print("第{}页爬取成功!".format(self.i))  # 打印break  # 跳出except Exception as e:print("Retry......")  # 捕捉异常def parse_html(self, html):"""function:  xpath提取数据函数in:  html:响应内容out:  Nonereturn:  Noneothers:  Extract Data By Xpath Function"""p = etree.HTML(html)  # 创造解析对象li_list = p.xpath("//li[@class='clear LOGVIEWDATA LOGCLICKDATA']")  # 解析对象调用xpathitem = {}  # 定义一个空字典for li in li_list:  # 遍历 解析对象调用xpath后 得到的数据name_list = li.xpath(".//div[@class='positionInfo']/a[1]/text()")item["名称"] = name_list[0].strip() if name_list else None  # 判断得到的名称列表是否为空address_list = li.xpath(".//div[@class='positionInfo']/a[2]/text()")item["地址"] = address_list[0].strip() if name_list else None  # 判断得到的地址列表是否为空info_li = li.xpath(".//div[@class='houseInfo']/text()")if info_li:  # 判断房源信息是否为空info_li = info_li[0].split("|")  # 用"|"分割if len(info_li) == 7:  # 长度=7item["户型"] = info_li[0].strip()item["面积"] = info_li[1].strip()item["朝向"] = info_li[2].strip()item["装修"] = info_li[3].strip()item["楼层"] = info_li[4].strip()item["年限"] = info_li[5].strip()item["种类"] = info_li[6].strip()else:if len(info_li) == 6:  # 长度=6item["户型"] = info_li[0].strip()item["面积"] = info_li[1].strip()item["朝向"] = info_li[2].strip()item["装修"] = info_li[3].strip()item["楼层"] = info_li[4].strip()item["种类"] = info_li[5].strip()else:if len(info_li) == 8:  # 长度=8item["户型"] = info_li[0].strip()item["面积"] = info_li[1].strip()item["朝向"] = info_li[2].strip()item["装修"] = info_li[3].strip()item["楼层"] = info_li[4].strip()item["年限"] = info_li[5].strip()item["种类"] = info_li[6].strip()item["种类"] += info_li[7].strip()else:item["户型"] = item["面积"] = item["朝向"] = item["装修"] = item["楼层"] = item["年限"] = item["种类"] = Noneelse:item["户型"] = item["面积"] = item["朝向"] = item["装修"] = item["楼层"] = item["年限"] = item["种类"] = Nonetotal_list = li.xpath(".//div[@class='totalPrice totalPrice2']/span/text()")item["总价"] = total_list[0].strip() if total_list else None  # 判断得到的总价列表是否为空unit_list = li.xpath(".//div[@class='unitPrice']/span/text()")item["单价"] = unit_list[0].strip() if unit_list else None  # 判断得到的单价列表是否为空print(item)  # 打印信息def run(self):"""function:  程序入口函数in:  Noneout:  Nonereturn:  Noneothers:  Program Entry Function"""for pg in range(1, 6):  # 爬取1-5页url = self.url.format(pg)  # 拼接url地址self.get_html(url)  # 调用 获取响应内容函数time.sleep(random.randint(1, 2))  # 1-2s延时if __name__ == '__main__':spider = LianjiaSpider()  # 类实例化spider.run()  # 调用入口函数

5、实现效果

在这里插入图片描述

这篇关于【Python_requests学习笔记(二)】基于requests和lxml模块,爬取链家房产数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/635840

相关文章

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

Python如何去除图片干扰代码示例

《Python如何去除图片干扰代码示例》图片降噪是一个广泛应用于图像处理的技术,可以提高图像质量和相关应用的效果,:本文主要介绍Python如何去除图片干扰的相关资料,文中通过代码介绍的非常详细,... 目录一、噪声去除1. 高斯噪声(像素值正态分布扰动)2. 椒盐噪声(随机黑白像素点)3. 复杂噪声(如伪

Python中图片与PDF识别文本(OCR)的全面指南

《Python中图片与PDF识别文本(OCR)的全面指南》在数据爆炸时代,80%的企业数据以非结构化形式存在,其中PDF和图像是最主要的载体,本文将深入探索Python中OCR技术如何将这些数字纸张转... 目录一、OCR技术核心原理二、python图像识别四大工具库1. Pytesseract - 经典O

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py

python使用库爬取m3u8文件的示例

《python使用库爬取m3u8文件的示例》本文主要介绍了python使用库爬取m3u8文件的示例,可以使用requests、m3u8、ffmpeg等库,实现获取、解析、下载视频片段并合并等步骤,具有... 目录一、准备工作二、获取m3u8文件内容三、解析m3u8文件四、下载视频片段五、合并视频片段六、错误

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

一文深入详解Python的secrets模块

《一文深入详解Python的secrets模块》在构建涉及用户身份认证、权限管理、加密通信等系统时,开发者最不能忽视的一个问题就是“安全性”,Python在3.6版本中引入了专门面向安全用途的secr... 目录引言一、背景与动机:为什么需要 secrets 模块?二、secrets 模块的核心功能1. 基

python常见环境管理工具超全解析

《python常见环境管理工具超全解析》在Python开发中,管理多个项目及其依赖项通常是一个挑战,下面:本文主要介绍python常见环境管理工具的相关资料,文中通过代码介绍的非常详细,需要的朋友... 目录1. conda2. pip3. uvuv 工具自动创建和管理环境的特点4. setup.py5.