• 链家网房源价格信息的爬虫分析工具


    亿牛云代理.jpg

    导语

    链家网是中国最大的房地产交易平台之一,提供了全国各地的房源信息,包括价格、面积、户型、楼层、朝向、小区、地理位置等。这些信息对于房地产市场的分析和预测有着重要的价值,但是链家网并没有提供方便的数据接口,因此需要使用爬虫技术来抓取和分析这些数据。本文将介绍如何使用Scrapy框架和代理IP技术来实现一个链家网房源价格信息的爬虫分析工具,该工具可以根据指定的城市和区域,抓取并保存链家网上的房源信息,并对数据进行简单的统计和可视化。

    概述

    本文使用的爬虫技术主要包括以下几个方面:

    • Scrapy框架:Scrapy是一个用Python编写的开源爬虫框架,提供了强大的功能和灵活的扩展性,可以快速地开发高效的爬虫程序。
    • 代理IP技术:由于链家网有反爬虫机制,如果使用同一个IP地址频繁地访问网站,可能会被封禁或者返回错误页面。为了避免这种情况,可以使用代理IP技术,即通过不同的IP地址来访问目标网站,从而降低被检测到的风险,亿牛云爬虫代理是一个提供稳定、高效、安全的爬虫代理服务的平台,可以通过域名、端口、用户名、密码等方式来获取代理IP,并且支持多种协议和格式。

    正文

    爬虫项目结构

    本文使用Scrapy框架来创建一个名为lianjia的爬虫项目,其结构如下:

    lianjia/
    ├── lianjia/
    │   ├── __init__.py
    │   ├── items.py
    │   ├── middlewares.py
    │   ├── pipelines.py
    │   ├── settings.py
    │   └── spiders/
    │       ├── __init__.py
    │       └── lianjia_spider.py
    └── scrapy.cfg
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其中,主要涉及到以下几个文件:

    • items.py:定义了要抓取和保存的数据结构,即Item类。
    • middlewares.py:定义了用于处理请求和响应的中间件类,主要用于设置代理IP。
    • pipelines.py:定义了用于处理Item对象的管道类,主要用于保存数据到文件或数据库。
    • settings.py:定义了爬虫项目的全局配置参数,例如日志级别、并发数、下载延迟等。
    • lianjia_spider.py:定义了用于抓取链家网房源信息的爬虫类,即LianjiaSpider类。

    Item类定义

    在items.py文件中,定义了一个名为LianjiaItem的类,用于存储链家网房源信息。该类继承了scrapy.Item类,并定义了以下几个字段:

    • title:房源标题,例如“南北通透三居室 采光好 精装修”。
    • price:房源总价,单位为万元,例如“450”。
    • unit_price:房源单价,单位为元/平方米,例如“37889”。
    • area:房源面积,单位为平方米,例如“118.8”。
    • layout:房源户型,例如“3室2厅”。
    • floor:房源楼层,例如“中楼层(共6层)”。
    • direction:房源朝向,例如“南 北”。
    • community:房源所在小区,例如“金地名京”。
    • location:房源所在地理位置,包括区域、商圈和街道,例如“朝阳 望京 望京西园四区”。
    • url:房源详情页的链接,例如“https://bj.lianjia.com/ershoufang/101113667258.html”。

    LianjiaItem类的代码如下:

    # 导入scrapy模块
    import scrapy
    
    # 定义LianjiaItem类
    class LianjiaItem(scrapy.Item):
        # 定义字段
        title = scrapy.Field()
        price = scrapy.Field()
        unit_price = scrapy.Field()
        area = scrapy.Field()
        layout = scrapy.Field()
        floor = scrapy.Field()
        direction = scrapy.Field()
        community = scrapy.Field()
        location = scrapy.Field()
        url = scrapy.Field()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    中间件类定义

    在middlewares.py文件中,定义了一个名为ProxyMiddleware的类,用于设置代理IP。该类继承了scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware类,并重写了process_request方法。该方法的作用是在每个请求发送之前,根据亿牛云爬虫代理的域名、端口、用户名、密码等参数,生成一个代理IP,并将其设置到请求的meta属性中。这样,请求就会通过代理IP来访问目标网站。

    ProxyMiddleware类的代码如下:

    # 导入scrapy模块
    import scrapy
    # 导入HttpProxyMiddleware类
    from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware
    
    # 定义ProxyMiddleware类
    class ProxyMiddleware(HttpProxyMiddleware):
        # 重写process_request方法
        def process_request(self, request, spider):
            # 设置亿牛云 爬虫代理的域名、端口、用户名、密码等参数
            proxy_host = "www.16yun.cn"
            proxy_port = "7020"
            proxy_user = "16YUN"
            proxy_pass = "16IP"
    
            # 生成代理IP
            proxy_ip = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
    
            # 将代理IP设置到请求的meta属性中
            request.meta["proxy"] = proxy_ip
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    管道类定义

    在pipelines.py文件中,定义了一个名为LianjiaPipeline的类,用于保存数据到文件或数据库。该类继承了scrapy.pipelines.files.FilesPipeline类,并重写了process_item方法。该方法的作用是在每个Item对象被抓取之后,将其转换为字典格式,并使用json模块将其追加到一个名为lianjia.json的文件中。这样,就可以将所有抓取到的数据保存到一个文件中。

    LianjiaPipeline类的代码如下:

    # 导入scrapy模块
    import scrapy
    # 导入FilesPipeline类
    from scrapy.pipelines.files import FilesPipeline
    # 导入json模块
    import json
    
    # 定义LianjiaPipeline类
    class LianjiaPipeline(FilesPipeline):
        # 重写process_item方法
        def process_item(self, item, spider):
            # 将Item对象转换为字典格式
            data = dict(item)
    
            # 打开一个名为lianjia.json的文件,如果不存在则创建
            with open("lianjia.json", "a", encoding="utf-8") as f:
                # 使用json模块将数据转换为json格式,并追加到文件中,每行一个数据
                json.dump(data, f, ensure_ascii=False)
                f.write("\n")
    
            # 返回Item对象
            return item
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    配置参数设置

    在settings.py文件中,设置了一些爬虫项目的全局配置参数,例如日志级别、并发数、下载延迟等。这些参数可以根据实际情况进行调整,以提高爬虫的性能和稳定性。以下是一些重要的参数的说明:

    • LOG_LEVEL:设置日志的输出级别,可以选择DEBUG、INFO、WARNING、ERROR等,用于控制日志的详细程度。默认为INFO。
    • CONCURRENT_REQUESTS:设置并发请求的最大数量,即同时发送的请求的数量。默认为16。
    • DOWNLOAD_DELAY:设置下载请求之间的延迟时间,单位为秒。用于避免过快地访问目标网站,导致被封禁或者返回错误页面。默认为0。
    • ITEM_PIPELINES:设置启用的管道类及其优先级,用于处理Item对象。优先级越低,越先执行。本文只启用了LianjiaPipeline类,并设置其优先级为300。
    • DOWNLOADER_MIDDLEWARES:设置启用的中间件类及其优先级,用于处理请求和响应。优先级越低,越先执行。本文只启用了ProxyMiddleware类,并设置其优先级为100。

    settings.py文件的部分代码如下:

    # 设置日志级别
    LOG_LEVEL = "INFO"
    
    # 设置并发请求的最大数量
    CONCURRENT_REQUESTS = 16
    
    # 设置下载延迟
    DOWNLOAD_DELAY = 0.5
    
    # 设置启用的管道类及其优先级
    ITEM_PIPELINES = {
       "lianjia.pipelines.LianjiaPipeline": 300,
    }
    
    # 设置启用的中间件类及其优先级
    DOWNLOADER_MIDDLEWARES = {
       "lianjia.middlewares.ProxyMiddleware": 100,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    爬虫类定义

    在lianjia_spider.py文件中,定义了一个名为LianjiaSpider的类,用于抓取链家网房源信息。该类继承了scrapy.Spider类,并定义了以下几个属性和方法:

    • name:爬虫的名称,用于运行爬虫时指定。本文设置为"lianjia"。
    • allowed_domains:允许爬取的域名列表,用于过滤不相关的链接。本文设置为[“lianjia.com”]。
    • start_urls:起始URL列表,用于开始爬取的页面。本文根据指定的城市和区域,生成对应的链家网二手房列表页的链接。
    • parse:解析响应的方法,用于提取数据和链接。本文使用XPath语法来提取房源信息和下一页链接,并生成Item对象和Request对象。

    LianjiaSpider类的代码如下:

    # 导入scrapy模块
    import scrapy
    # 导入LianjiaItem类
    from lianjia.items import LianjiaItem
    
    # 定义LianjiaSpider类
    class LianjiaSpider(scrapy.Spider):
        # 定义爬虫名称
        name = "lianjia"
    
        # 定义允许爬取的域名列表
        allowed_domains = ["lianjia.com"]
    
        # 定义起始URL列表
        def start_requests(self):
            # 设置要爬取的城市和区域,可以根据需要修改
            city = "bj"
            region = "chaoyang"
    
            # 生成起始URL
            start_url = f"https://{city}.lianjia.com/ershoufang/{region}/"
    
            # 发送请求,并指定回调函数为parse
            yield scrapy.Request(url=start_url, callback=self.parse)
    
        # 定义解析响应的方法
        def parse(self, response):
            # 使用XPath语法提取房源信息列表
            house_list = response.xpath("//ul[@class='sellListContent']/li")
    
            # 遍历房源信息列表
            for house in house_list:
                # 创建一个LianjiaItem对象
                item = LianjiaItem()
    
                # 提取房源标题,并赋值给item的title字段
                item["title"] = house.xpath(".//div[@class='title']/a/text()").get()
    
                # 提取房源总价,并赋值给item的price字段
                item["price"] = house.xpath(".//div[@class='priceInfo']/div[@class='totalPrice']/span/text()").get()
    
                # 提取房源单价,并赋值给item的unit_price字段
                item["unit_price"] = house.xpath(".//div[@class='priceInfo']/div[@class='unitPrice']/span/text()").get()
    
                # 提取房源面积,并赋值给item的area字段
                item["area"] = house.xpath(".//div[@class='houseInfo']/text()")\
                    .re_first(r"\d+\.?\d*平米")
    
                # 提取房源户型,并赋值给item的layout字段
                item["layout"] = house.xpath(".//div[@class='houseInfo']/text()")\
                    .re_first(r"\d+室\d+厅")
    
                # 提取房源楼层,并赋值给item的floor字段
                item["floor"] = house.xpath(".//div[@class='positionInfo']/text()")\
                    .re_first(r".*楼层")
    
                # 提取房源朝向,并赋值给item的direction字段
                item["direction"] = house.xpath(".//div[@class='positionInfo']/text()")\
                    .re_first(r"[东南西北 ]+")
    
                # 提取房源所在小区,并赋值给item的community字段
                item["community"] = house.xpath(".//div[@class='positionInfo']/a/text()")\
                    .get()
    
                # 提取房源所在地理位置,并赋值给item的location字段
                item["location"] = "".join(house.xpath(".//div[@class='positionInfo']/a/text()")\
                    .getall()[1:])
    
                # 提取房源详情页的链接,并赋值给item的url字段
                item["url"] = house.xpath(".//div[@class='title']/a/@href")\
                    .get()
    
                # 返回Item对象
                yield item
    
            # 使用XPath语法提取下一页链接
            next_page = response.xpath("//div[@class='page-box fr']//@page-url")\
                .get()
    
            # 如果存在下一页链接,继续发送请求,并指定回调函数为parse
            if next_page:
                # 拼接完整的URL
                next_url = response.urljoin(next_page)
    
                # 发送请求,并指定回调函数为parse
                yield scrapy.Request(url=next_url, callback=self.parse)
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    结语

    本文介绍了如何使用Scrapy框架和代理IP技术来实现一个链家网房源价格信息的爬虫分析工具,该工具可以根据指定的城市和区域,抓取并保存链家网上的房源信息,并对数据进行简单的统计和可视化。本文只是一个简单的示例,实际应用中还可以根据需要进行更多的优化和扩展,例如增加异常处理、增加数据清洗、增加数据分析、增加数据可视化等。希望本文能对你有所帮助,谢谢!

  • 相关阅读:
    SQL语句学习
    [NOIP2013 普及组] 计数问题
    基于Java的厨艺交流平台设计与实现(源码+lw+部署文档+讲解等)
    Turtle绘制五角星-第10届蓝桥杯省赛Python真题精选
    2024年阿里云大数据acp认证条件
    MySQL 主从复制与读写分离
    【Swift 60秒】03 - Multi-line strings
    怎样创建Oracle的dbms_jobs(数据库任务)
    libtorch 部署YOLOv5 GPU版本
    行政事业单位固定资产管理系统,资产管理系统操作手册
  • 原文地址:https://blog.csdn.net/ip16yun/article/details/133029539