Python爬虫实战:监控贝壳找房小区均价与挂牌增量!

㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~

㊙️本期爬虫难度指数:⭐⭐⭐

🉐福利: 一次订阅后,专栏内的所有文章可永久免费看,持续更新中,保底1000+(篇)硬核实战内容。

全文目录:

      • [🌟 开篇语](#🌟 开篇语)
      • [0️⃣ 前言(Preface)](#0️⃣ 前言(Preface))
      • [1️⃣ 摘要(Abstract)](#1️⃣ 摘要(Abstract))
      • [2️⃣ 背景与需求(Why)](#2️⃣ 背景与需求(Why))
      • [3️⃣ 合规与注意事项(必写)](#3️⃣ 合规与注意事项(必写))
      • [4️⃣ 技术选型与整体流程(What/How)](#4️⃣ 技术选型与整体流程(What/How))
      • [5️⃣ 环境准备与依赖安装(可复现)](#5️⃣ 环境准备与依赖安装(可复现))
      • [6️⃣ 核心实现:请求层(Fetcher)](#6️⃣ 核心实现:请求层(Fetcher))
      • [7️⃣ 核心实现:解析层(Parser)](#7️⃣ 核心实现:解析层(Parser))
      • [8️⃣ 数据存储与导出(Storage)](#8️⃣ 数据存储与导出(Storage))
      • [9️⃣ 运行方式与结果展示(必写)](#9️⃣ 运行方式与结果展示(必写))
      • [🔟 常见问题与排错(强烈建议写)](#🔟 常见问题与排错(强烈建议写))
      • [1️⃣1️⃣ 进阶优化(可选但加分)](#1️⃣1️⃣ 进阶优化(可选但加分))
      • [1️⃣2️⃣ 总结与延伸阅读](#1️⃣2️⃣ 总结与延伸阅读)
      • [🌟 文末](#🌟 文末)
        • [✅ 专栏持续更新中|建议收藏 + 订阅](#✅ 专栏持续更新中|建议收藏 + 订阅)
        • [✅ 互动征集](#✅ 互动征集)
        • [✅ 免责声明](#✅ 免责声明)

🌟 开篇语

哈喽,各位小伙伴们你们好呀~我是【喵手】。

运营社区: C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO

欢迎大家常来逛逛,一起学习,一起进步~🌟

我长期专注 Python 爬虫工程化实战 ,主理专栏 《Python爬虫实战》:从采集策略反爬对抗 ,从数据清洗分布式调度 ,持续输出可复用的方法论与可落地案例。内容主打一个"能跑、能用、能扩展 ",让数据价值真正做到------抓得到、洗得净、用得上

📌 专栏食用指南(建议收藏)

  • ✅ 入门基础:环境搭建 / 请求与解析 / 数据落库
  • ✅ 进阶提升:登录鉴权 / 动态渲染 / 反爬对抗
  • ✅ 工程实战:异步并发 / 分布式调度 / 监控与容错
  • ✅ 项目落地:数据治理 / 可视化分析 / 场景化应用

📣 专栏推广时间 :如果你想系统学爬虫,而不是碎片化东拼西凑,欢迎订阅专栏👉《Python爬虫实战》👈,一次订阅后,专栏内的所有文章可永久免费阅读,持续更新中。

💕订阅后更新会优先推送,按目录学习更高效💯~

0️⃣ 前言(Preface)

  • 本文目标 :利用 Python + requests + lxml 采集贝壳找房(Ke.com)小区榜单,并结合 SQLite 实现小区价格与在售房源数的增量监控。

  • 读完收益

    1. 掌握针对贝壳复杂 HTML 结构的 XPath 精准提取
    2. 学会利用数据库 Upsert (更新或插入) 逻辑实现价格波动监控。
    3. 构建一套自动对比"昨日 vs 今日"数据的监控报表逻辑。

1️⃣ 摘要(Abstract)

本文聚焦于房产市场最核心的指标------"小区均价"与"挂牌量"。我们将通过模拟浏览器请求获取贝壳小区频道的分页数据,利用本地数据库保存历史快照。通过对比两次采集的时间戳,自动识别出价格异动的小区,最终产出 beike_housing_monitor.db 数据库。

2️⃣ 背景与需求(Why)

为什么要爬?

单看某一天的房价没意义,趋势才有意义

  • 抄底时机:监控某小区在售房源数突然激增,可能预示价格下行。
  • 价值分析:对比同区域不同小区的成交活跃度(通过挂牌量变化推算)。

目标字段清单:

字段名 含义 示例
community_id 小区唯一ID 1111027377528
community_name 小区名称 华润二十四城
city 城市 成都
avg_price 均价 (元/㎡) 32500
on_sale_count 在售房源数 125
total_listings 30天内挂牌量 15

3️⃣ 合规与注意事项(必写)

  1. robots.txt:贝壳对爬虫非常敏感,严禁高频率并发请求。
  2. 频率控制 :建议单线程运行,每个请求间隔 3-5 秒,模仿正常用户的浏览行为。
  3. 敏感信息:本文仅抓取小区维度的公开统计数据,不涉及任何具体业主隐私或联系方式。
  4. IP 保护:如遇到验证码,请立即停止脚本,切勿暴力破解。

4️⃣ 技术选型与整体流程(What/How)

  • 选型requests (高效请求) + lxml (极速解析) + sqlite3 (本地结构化存储)。

  • 流程

    1. 入口:拼接城市缩写和区域 URL。
    2. 翻页 :解析分页组件,循环请求 pg1pgN
    3. 解析:提取小区 ID、均价、房源数等。
    4. 对比 :查询数据库,若已存在该 ID,则对比 avg_price,记录变动值。
    5. 更新:写入最新数据。

5️⃣ 环境准备与依赖安装(可复现)

项目结构建议:

text 复制代码
Beike_Monitor/
├── data/
│   └── beike_housing_monitor.db  # 增量数据库
├── logs/
├── beike_tracker.py              # 主程序
└── requirements.txt

安装命令:

bash 复制代码
pip install requests lxml pandas

6️⃣ 核心实现:请求层(Fetcher)

贝壳对 User-Agent 校验较严,建议准备一个简单的 UA 池。

python 复制代码
import requests
import time

class BeikeFetcher:
    def __init__(self):
        self.session = requests.Session()
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Referer': 'https://cd.ke.com/xiaoqu/'
        }

    def fetch(self, url):
        try:
            # Gentle crawl
            time.sleep(3) 
            response = self.session.get(url, headers=self.headers, timeout=10)
            if response.status_code == 200:
                return response.text
            return None
        except Exception as e:
            print(f"Error fetching {url}: {e}")
            return None

7️⃣ 核心实现:解析层(Parser)

利用 XPath 精准定位小区卡片。

python 复制代码
from lxml import etree

def parse_community_list(html_content):
    tree = etree.HTML(html_content)
    # 定位小区列表容器
    nodes = tree.xpath('//li[@class="xiaoquListItem"]')
    
    results = []
    for node in nodes:
        # 贝壳的小区ID通常藏在 data-id 或 href 中
        comm_id = node.xpath('./@data-id')[0]
        name = node.xpath('.//div[@class="title"]/a/text()')[0].strip()
        # 均价可能存在"暂无"
        price_raw = node.xpath('.//div[@class="totalPrice"]/span/text()')[0]
        price = int(price_raw) if price_raw.isdigit() else 0
        
        # 在售房源数
        on_sale = node.xpath('.//div[@class="xiaoquListItemSellCount"]/a/span/text()')[0]
        
        results.append({
            'id': comm_id,
            'name': name,
            'price': price,
            'on_sale': int(on_sale)
        })
    return results

8️⃣ 数据存储与导出(Storage)

使用 SQLite 实现"增量监控"的核心逻辑。

python 复制代码
import sqlite3

def save_and_compare(data_list, city_name):
    conn = sqlite3.connect('beike_housing_monitor.db')
    cursor = conn.cursor()
    
    # Create table if not exists
    cursor.execute('''CREATE TABLE IF NOT EXISTS communities 
                     (id TEXT PRIMARY KEY, name TEXT, city TEXT, 
                      old_price INTEGER, new_price INTEGER, 
                      on_sale INTEGER, last_update TIMESTAMP)''')

    for item in data_list:
        # 检查是否存在旧数据
        cursor.execute("SELECT new_price FROM communities WHERE id=?", (item['id'],))
        row = cursor.fetchone()
        
        if row:
            old_p = row[0]
            if old_p != item['price']:
                print(f"🚩 价格变动!{item['name']}: {old_p} -> {item['price']}")
            
            cursor.execute('''UPDATE communities SET old_price=?, new_price=?, on_sale=?, last_update=datetime('now')
                              WHERE id=?''', (old_p, item['price'], item['on_sale'], item['id']))
        else:
            cursor.execute('''INSERT INTO communities VALUES (?, ?, ?, ?, ?, ?, datetime('now'))''',
                           (item['id'], item['name'], city_name, 0, item['price'], item['on_sale']))
    
    conn.commit()
    conn.close()

9️⃣ 运行方式与结果展示(必写)

运行命令:

bash 复制代码
python beike_tracker.py --city cd

控制台示例结果:

text 复制代码
🚀 Starting Beike Monitor for City: cd
📡 Scraping Page 1...
✅ Found 30 communities.
🚩 Price Change! Community [Blue Town]: 21000 -> 20500
💾 Database updated.

🔟 常见问题与排错(强烈建议写)

  • HTML 返回空壳? 贝壳有时会检测到异常流量并重定向到验证码页面。对策 :检查 Headers 里的 Cookie 是否过期,或者大幅度调低抓取速度。
  • 均价显示"暂无"? 部分新开盘或成交极少的小区没有均价。对策 :在解析层增加 try-exceptisdigit() 判断。
  • 分页截断? 贝壳列表页只显示前 100 页。对策:细化区域(District)甚至街道(Bizcircle),分拆 URL 进行抓取。

1️⃣1️⃣ 进阶优化(可选但加分)

  • 数据可视化 (Visualizations):使用 Matplotlib 生成趋势图。注意:所有标题和标签均使用英文。

    • Chart Title : Community Price Volatility Distribution
    • X-axis : Community Name, Y-axis : Price Change (RMB)
  • 自动化推送:集成钉钉或企业微信机器人,当监控到涨跌幅超过 5% 时自动报警。

  • 定时任务 :配置 Crontab 每天凌晨 2 点执行,实现真正的"无人值守监控"。

1️⃣2️⃣ 总结与延伸阅读

  • 复盘:我们不仅完成了数据的"抓取",更通过本地数据库实现了"时间维度"上的增量追踪。
  • 延伸 :下一步可以尝试爬取"成交历史数据",将挂牌价与成交价进行对比,计算议价空间,那才是真正的硬核金融分析!

🌟 文末

好啦~以上就是本期的全部内容啦!如果你在实践过程中遇到任何疑问,欢迎在评论区留言交流,我看到都会尽量回复~咱们下期见!

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦~
三连就是对我写作道路上最好的鼓励与支持! ❤️🔥

✅ 专栏持续更新中|建议收藏 + 订阅

墙裂推荐订阅专栏 👉 《Python爬虫实战》,本专栏秉承着以"入门 → 进阶 → 工程化 → 项目落地"的路线持续更新,争取让每一期内容都做到:

✅ 讲得清楚(原理)|✅ 跑得起来(代码)|✅ 用得上(场景)|✅ 扛得住(工程化)

📣 想系统提升的小伙伴 :强烈建议先订阅专栏 《Python爬虫实战》,再按目录大纲顺序学习,效率十倍上升~

✅ 互动征集

想让我把【某站点/某反爬/某验证码/某分布式方案】等写成某期实战?

评论区留言告诉我你的需求,我会优先安排实现(更新)哒~


⭐️ 若喜欢我,就请关注我叭~(更新不迷路)

⭐️ 若对你有用,就请点赞支持一下叭~(给我一点点动力)

⭐️ 若有疑问,就请评论留言告诉我叭~(我会补坑 & 更新迭代)


✅ 免责声明

本文爬虫思路、相关技术和代码仅用于学习参考,对阅读本文后的进行爬虫行为的用户本作者不承担任何法律责任。

使用或者参考本项目即表示您已阅读并同意以下条款:

  • 合法使用: 不得将本项目用于任何违法、违规或侵犯他人权益的行为,包括但不限于网络攻击、诈骗、绕过身份验证、未经授权的数据抓取等。
  • 风险自负: 任何因使用本项目而产生的法律责任、技术风险或经济损失,由使用者自行承担,项目作者不承担任何形式的责任。
  • 禁止滥用: 不得将本项目用于违法牟利、黑产活动或其他不当商业用途。
  • 使用或者参考本项目即视为同意上述条款,即 "谁使用,谁负责" 。如不同意,请立即停止使用并删除本项目。!!!
相关推荐
不会写DN3 小时前
golang的fs除了定权限还能干什么?
开发语言·爬虫·golang
WJSKad12353 小时前
如何评价ControlNet v1.1的InPaint版本?[特殊字符]
python
xuansec3 小时前
【JavaEE安全】JNDI 注入从原理到实战:RMI、LDAP 与高版本绕过
python·安全·java-ee
进击的雷神3 小时前
前端路由动态渲染、JSON内嵌HTML清洗、展位信息数组化、分页参数固定化——尼日利亚展会爬虫四大技术难关攻克纪实
前端·爬虫·python·json
梁正雄4 小时前
Python前端-2-css基础
前端·python·html
MoRanzhi12034 小时前
Pillow 图像颜色模式与颜色空间转换
图像处理·python·数学建模·pillow·颜色空间转换·颜色模式·图像通道
&Darker4 小时前
十三、大语言模型微调
人工智能·python·语言模型
小白学大数据5 小时前
对比分析:Python爬虫模拟登录的3种主流实现方式
开发语言·爬虫·python·数据分析
与虾牵手5 小时前
用 Python 从零搭一个能用的 AI Agent,踩完坑我总结了这套模板
python·aigc·ai编程