Python安居客二手小区数据爬取(2025年)

目录

  • 2025年安居客二手小区数据爬取
    • 观察目标网页
    • 观察详情页数据
    • 准备工作:安装装备就像打游戏
    • 代码详解:每行代码都是你的小兵
    • 完整代码大放送
    • 爬取结果

2025年安居客二手小区数据爬取

这段时间需要爬取安居客二手小区数据,看了一下相关教程基本也都有点久远,趁着新年期间我也把自己爬取的思路跟流程记录一下(适合有一点爬虫基础的宝宝食用),如有不对,欢迎私信交流~

观察目标网页

我们这里爬取的是安居客二手小区数据,从官网进去
在这里插入图片描述
这里看到小区的总数量,以及相关的小区的名字等信息,红框框起来的数据一般是我们所关心的
在这里插入图片描述
当然,点击小区可以进入详情页,这里列出了关于该小区更加具体的信息,我们这里尝试把框起来的数据都爬取下来!
在这里插入图片描述
知道了我们需要爬取的数据之后,下一步我们需要进一步分析这些数据的来源——数据是写在静态网页中还是从服务器异步加载过来的,让我们分析一下网页结构:
在这里插入图片描述
从上面这张图里我们可以发现数据是写在了html的源码里的,每个小区的数据都包裹在一个li-row的a标签里面,因此我们只需要把list-cell里面的所有li-row都遍历一遍,就可以获取一页的小区相关数据,当然这里还没包含详情页数据~
在这里插入图片描述

观察详情页数据

在这里插入图片描述
我们可以发现这个小区详情页的数据会存放在maininfo的div大盒子里面,然后这个大盒子里由house-price跟info两个div小盒子组成,因此我们只需要从这两个小盒子里取数据即可~下面开始搓我们的代码!

准备工作:安装装备就像打游戏

1️⃣ 装Python环境(不会的看这里)
👉 去Python官网下载最新版,安装时记得勾选"Add Python to PATH"
2️⃣ 安装必备武器库(打开cmd / powershell)

pip install requests beautifulsoup4

💡 这俩库相当于你的"爬虫工具箱",一个负责上网,一个负责解析网页
3️⃣ 准备VIP通行证 (Cookie获取)
cookie的作用可以让我们在模拟登陆的时候维持一下会话,因为安居客这个网站每隔一段时间就需要输入一下验证码或者重新登陆,设置一下cookie方便很多!!!
具体自己浏览器的cookie在登陆之后,按F12打开开发者工具,找到Network标签 → 刷新页面 → 随便选个请求 → 复制一下响应标头里的set-cookie里的内容即可~
在这里插入图片描述

代码详解:每行代码都是你的小兵

🛠️ 先看整体作战计划:

"""
作战目标:自动抓取指定数量的小区信息
作战路线:列表页 → 详情页 → 数据保存
武器配置:requests发请求,BeautifulSoup解析
特殊装备:自动重试机制防掉线
"""

🎯 核心代码拆解(重点!)

  1. 配置侦察兵参数
# 伪装成浏览器(重要!)
HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)...'  # 完整UA太长省略
}

# 你的VIP通行证(定期更新!)
COOKIES = {
    'ajkAuthTicket': 'TT=3f67c23d85c369b7018fcb4e...',  # 填你复制的Cookie
    'ctid': '24'
}
  1. 创建不死鸟连接器
def create_session():
    session = requests.Session()
    # 配置自动重试(网络不好也不怕)
    adapter = HTTPAdapter(max_retries=Retry(
        total=3, 
        backoff_factor=1,
        status_forcelist=[500, 502, 503, 504]
    ))
    session.mount('https://', adapter)
    return session

💡 这个相当于你的"网络保镖",遇到问题自动重试三次
3. 万能数据提取器

def safe_get_text(element, selector, default='N/A'):
    """ 安全提取文本,找不到元素也不报错 """
    target = element.select_one(selector)
    return target.text.strip() if target else default

🌟 使用场景:就像用镊子精准夹取页面数据,夹不到就返回默认值
4. 主力作战部队(main函数)

def main():
    # 输入要抓多少小区
    community_count = int(input("想抓多少小区?输入数字:"))
    
    # 创建侦察兵小队
    with open('小区数据.csv', 'w', encoding='utf-8') as f:
        writer = csv.writer(f)
        writer.writerow(['小区名称', '价格', '地址', ...])  # 完整表头
        
        # 开始翻页抓取
        for page in range(1, 总页数+1):
            # 获取当前页所有小区链接
            # 逐个访问详情页提取数据
            # 保存到CSV
            # 休息0.5秒防止被封

💡 这里用了with open自动管理文件,就像有个小秘书帮你保存数据

完整代码大放送

"""
安居客小区信息爬虫 
"""
import csv
import time
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from bs4 import BeautifulSoup

# ========================== 全局配置 ==========================
# 请求头配置(模拟浏览器访问)
HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0',
    'Referer': 'https://member.anjuke.com/',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
}

# Cookies配置(需要定期更新)
COOKIES = {
    'ajkAuthTicket': 'TT=3f67c23d85c369b7018fcb4e1418466f&TS=1738219179437&PBODY=IotzzfNhkTJKGH_LuUrSfcNHUGin1wBsHjAQYBL3k0USZDHrUxL6RQUv1ZsFPDHjxvQl0uvU2zSgIEdSFCHUc7wYEf4slKV2U2F9rwNnp6xHgufTxMgdYWZEob_Tep-poDqBMbQQgayOQhsaRgVjw8K8ut3QqqMfPgYGpKJJBHw&VER=2&CUID=fzgJGetduRhII81NXadF-HKyO1Hvr8W-',
    'ctid': '24',
}

# 重试策略配置
RETRY_STRATEGY = Retry(
    total=3,  # 最大重试次数
    backoff_factor=1,  # 重试等待时间因子
    status_forcelist=[500, 502, 503, 504],  # 需要重试的状态码
    allowed_methods=frozenset(['GET', 'POST'])  # 允许重试的HTTP方法
)

# 其他配置
BASE_URL = 'https://foshan.anjuke.com/community/p{page}/'  # 分页URL模板
REQUEST_DELAY = 0.5  # 请求间隔时间(秒),防止被封禁
CSV_HEADERS = [  # CSV文件表头
    '小区名称', '价格', '地址', '小区链接',
    '物业类型', '权属类别', '竣工时间', '产权年限', '总户数', '总建筑面积', '容积率', 
    '绿化率', '建筑类型', '所属商圈', '统一供暖', '供水供电', '停车位', '物业费',
    '停车费', '车位管理费', '物业公司', '小区地址', '开发商', '在售房源', '在租房源'
]

# ========================== 工具函数 ==========================
def create_session():
    """
    创建带有重试策略的请求会话
    返回:
        requests.Session - 配置好的会话对象
    """
    session = requests.Session()
    adapter = HTTPAdapter(max_retries=RETRY_STRATEGY)
    session.mount('https://', adapter)
    session.mount('http://', adapter)
    return session

def safe_get_text(element, selector, default='N/A'):
    """
    安全获取元素文本内容
    参数:
        element: BeautifulSoup对象 - 父元素
        selector: str - CSS选择器
        default: str - 默认返回值
    返回:
        str - 元素的文本内容或默认值
    """
    target = element.select_one(selector)
    return target.get_text(strip=True) if target else default

# ========================== 主程序 ==========================
def main():
    # 用户输入
    community_count = int(input("请输入需要抓取的小区数量:"))
    
    # 初始化会话
    session = create_session()
    
    # 准备CSV文件
    with open('communities.csv', mode='w', newline='', encoding='utf-8') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(CSV_HEADERS)
        
        page_count = (community_count // 25) + (1 if community_count % 25 else 0)
        collected = 0  # 已收集数量
        
        # 分页抓取
        for current_page in range(1, page_count + 1):
            print(f"\n➤ 正在处理第 {current_page}/{page_count} 页...")
            
            # 获取列表页
            try:
                list_url = BASE_URL.format(page=current_page)
                response = session.get(
                    list_url,
                    headers=HEADERS,
                    cookies=COOKIES,
                    timeout=10
                )
                response.raise_for_status()
            except Exception as e:
                print(f"⚠️ 列表页请求失败: {e}")
                continue
            
            # 解析小区列表
            list_soup = BeautifulSoup(response.text, 'html.parser')
            communities = list_soup.find_all('a', class_='li-row')
            
            # 遍历每个小区
            for community in communities:
                if collected >= community_count:
                    break
                
                # 提取基本信息
                name = safe_get_text(community, 'div.li-title')
                price = safe_get_text(community, 'div.community-price')
                address = safe_get_text(community, 'div.props')
                link = community.get('href', '')
                print(f"\n▌ 正在处理小区:{name}")
                
                # 获取详情页
                try:
                    detail_response = session.get(
                        link,
                        headers=HEADERS,
                        cookies=COOKIES,
                        timeout=15
                    )
                    detail_response.raise_for_status()
                except Exception as e:
                    print(f"  ⚠️ 详情页请求失败: {e}")
                    continue
                
                # 解析详情页
                detail_soup = BeautifulSoup(detail_response.text, 'html.parser')
                details = []
                
                # 提取主要信息
                for index in range(14):  # 0-13对应预设的标签
                    value = safe_get_text(detail_soup, f'div.value.value_{index}')
                    details.append(value)
                
                # 提取额外信息
                extra_info = {
                    '停车费': 'N/A',
                    '车位管理费': 'N/A',
                    '物业公司': 'N/A',
                    '小区地址': 'N/A',
                    '开发商': 'N/A'
                }
                for column in detail_soup.find_all('div', class_='column-1'):
                    label = safe_get_text(column, 'div.label')
                    value = safe_get_text(column, 'div.value')
                    for key in extra_info:
                        if key in label:
                            extra_info[key] = value
                
                # 提取房源信息
                sale = detail_soup.find('div', class_='sale')
                rent = detail_soup.find('div', class_='rent')
                sale_info = f"{safe_get_text(sale, 'i.source-number')} {safe_get_text(sale, 'i.source-unit')}" if sale else 'N/A'
                rent_info = f"{safe_get_text(rent, 'i.source-number')} {safe_get_text(rent, 'i.source-unit')}" if rent else 'N/A'
                
                # 构建完整数据行
                row = [
                    name, price, address, link,
                    *details,
                    *extra_info.values(),
                    sale_info, rent_info
                ]
                
                # 写入CSV
                writer.writerow(row)
                collected += 1
                print(f"  ✅ 已保存 {collected}/{community_count} - {name}")
                
                # 请求间隔
                time.sleep(REQUEST_DELAY)
                
    print("\n🎉 数据抓取完成!结果已保存到 communities.csv")

if __name__ == '__main__':
    main()

爬取结果

这是爬取的结果,如果只要其中的部分列,我建议直接删除最终的csv表格,而不是修改代码,代码能运行就尽量别动 -_-!!!
在这里插入图片描述

在这里插入图片描述
完结撒花~

参考文章:
[1]: 菜鸟爬虫——获取安居客二手房信息
[2]:Python爬虫之路(9)–an居客数据获取
[3]:Python之爬取安居客网二手房小区详情页数据
[4]:python使用代理爬取安居客二手房数据(一)
[5]:(项目)爬取安居客二手房房屋信息
[6]:【爬虫】安居客二手房数据爬取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/963087.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Electron使用WebAassembly实现CRC-8 MAXIM校验

Electron使用WebAssembly实现CRC-8 MAXIM校验 将C/C语言代码,经由WebAssembly编译为库函数,可以在JS语言环境进行调用。这里介绍在Electron工具环境使用WebAssembly调用CRC-8 MAXIM格式校验的方式。 CRC-8 MAXIM校验函数WebAssebly源文件 C语言实现CR…

DeepSeek-R1:通过强化学习激励大型语言模型(LLMs)的推理能力

摘要 我们推出了第一代推理模型:DeepSeek-R1-Zero和DeepSeek-R1。DeepSeek-R1-Zero是一个未经监督微调(SFT)作为初步步骤,而是通过大规模强化学习(RL)训练的模型,展现出卓越的推理能力。通过强…

pytorch基于FastText实现词嵌入

FastText 是 Facebook AI Research 提出的 改进版 Word2Vec,可以: ✅ 利用 n-grams 处理未登录词 比 Word2Vec 更快、更准确 适用于中文等形态丰富的语言 完整的 PyTorch FastText 代码(基于中文语料),包含&#xff1…

【hot100】刷题记录(8)-矩阵置零

题目描述: 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例 2…

PyTorch框架——基于深度学习YOLOv8神经网络学生课堂行为检测识别系统

基于YOLOv8深度学习的学生课堂行为检测识别系统,其能识别三种学生课堂行为:names: [举手, 读书, 写字] 具体图片见如下: 第一步:YOLOv8介绍 YOLOv8 是 ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本…

Doki Doki Mods Maker小指南

-*- 做都做了,那就做到底吧。 -*- 前言: 项目的话,在莫盘里,在贴吧原帖下我有发具体地址。 这里是Doki Doki Mods Maker,是用来做DDLC Mods的小工具。 说是“Mods”,实则不然,这个是我从零仿…

nodejs:express + js-mdict 网页查询英汉词典

向 DeepSeek R1 提问: 我想写一个Web 前端网页,后台用 nodejs js-mdict, 实现在线查询英语单词 1. 项目结构 首先,创建一个项目目录,结构如下: mydict-app/ ├── public/ │ ├── index.html │ ├── st…

LabVIEW纤维集合体微电流测试仪

LabVIEW开发纤维集合体微电流测试仪。该设备精确测量纤维材料在特定电压下的电流变化,以分析纤维的结构、老化及回潮率等属性,对于纤维材料的科学研究及质量控制具有重要意义。 ​ 项目背景 在纤维材料的研究与应用中,电学性能是评估其性能…

dfs枚举问题

碎碎念:要开始刷算法题备战蓝桥杯了,一切的开头一定是dfs 定义 枚举问题就是咱数学上学到的,从n个数里面选m个数,有三种题型(来自Acwing) 从 1∼n 这 n个整数中随机选取任意多个,输出所有可能的选择方案。 把 1∼n这…

SOME/IP--协议英文原文讲解3

前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 Note: Thi…

leetcode——二叉树的中序遍历(java)

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2] 示例 2: 输入:root [] 输出:[] 示例 3: 输入:root [1] 输出…

91,【7】 攻防世界 web fileclude

进入靶场 <?php // 包含 flag.php 文件 include("flag.php");// 以高亮语法显示当前文件&#xff08;即包含这段代码的 PHP 文件&#xff09;的内容 // 方便查看当前代码结构和逻辑&#xff0c;常用于调试或给解题者提示代码信息 highlight_file(__FILE__);// 检…

Microsoft Power BI:融合 AI 的文本分析

Microsoft Power BI 是微软推出的一款功能强大的商业智能工具&#xff0c;旨在帮助用户从各种数据源中提取、分析和可视化数据&#xff0c;以支持业务决策和洞察。以下是关于 Power BI 的深度介绍&#xff1a; 1. 核心功能与特点 Power BI 提供了全面的数据分析和可视化功能&…

海外问卷调查,最常用到的渠道查有什么特殊之处

市场调研&#xff0c;包含市场调查和市场研究两个步骤&#xff0c;是企业和机构根据经营方向而做出的决策问题&#xff0c;最终通过海外问卷调查中的渠道查&#xff0c;来系统地设计、收集、记录、整理、分析、研究市场反馈的工作流程。 市场调研的工作流程包括&#xff1a;确…

《苍穹外卖》项目学习记录-Day10来单提醒

type&#xff1a;用来标识消息的类型&#xff0c;比如说type1表示来单提醒&#xff0c;type2表示客户催单。 orderId&#xff1a;表示订单id&#xff0c;因为不管是来单提醒还是客户催单&#xff0c;这一次提醒都对应一个订单。是用户下了某个单或者催促某个订单&#xff0c;这…

【全栈】SprintBoot+vue3迷你商城(10)

【全栈】SprintBootvue3迷你商城&#xff08;10&#xff09; 往期的文章都在这里啦&#xff0c;大家有兴趣可以看一下 后端部分&#xff1a; 【全栈】SprintBootvue3迷你商城&#xff08;1&#xff09; 【全栈】SprintBootvue3迷你商城&#xff08;2&#xff09; 【全栈】Sp…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.27 线性代数王国:矩阵分解实战指南

1.27 线性代数王国&#xff1a;矩阵分解实战指南 #mermaid-svg-JWrp2JAP9qkdS2A7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JWrp2JAP9qkdS2A7 .error-icon{fill:#552222;}#mermaid-svg-JWrp2JAP9qkdS2A7 .erro…

【愚公系列】《循序渐进Vue.js 3.x前端开发实践》030-自定义组件的插槽Mixin

标题详情作者简介愚公搬代码头衔华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xff0c;阿里云签约作者&#xff0c;腾讯云优秀博主&…

langchain 实现多智能体多轮对话

这里写目录标题 工具定义模型选择graph节点函数定义graph 运行 工具定义 import random from typing import Annotated, Literalfrom langchain_core.tools import tool from langchain_core.tools.base import InjectedToolCallId from langgraph.prebuilt import InjectedSt…

pytorch生成对抗网络

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 生成对抗网络&#xff08;GAN&#xff0c;Generative Adversarial Network&#xff09;是一种深度学习模型&#xff0c;由两个神经网络组成&#xff1a;生成器&#xff08;Generator&#xff09;和判别器&#xff0…