汽车之家车型参数对比表爬取

在汽车消费决策中,车型参数对比是核心环节。汽车之家作为国内权威汽车资讯平台,汇聚了海量车型的详细参数,但手动整理效率极低。本文将从页面分析、反爬应对、代码实现、数据存储四大维度,手把手教你用 Python 高效爬取汽车之家车型参数对比表,实现数据自动化采集与结构化输出。

一、爬取前的核心准备

1. 技术栈选型

本次爬取采用轻量高效的 Python 技术组合,兼顾开发效率与反爬适配:

  • 请求库requests------ 发送 HTTP 请求,模拟浏览器访问
  • 解析库BeautifulSoup4------ 解析 HTML 页面,提取参数数据
  • 数据处理pandas------ 结构化数据,生成对比表并导出为 CSV/Excel
  • 反爬工具fake_useragent------ 随机生成 User-Agent,time------ 设置请求延时

安装依赖命令:

bash

运行

复制代码
pip install requests beautifulsoup4 pandas fake_useragent

2. 页面结构与接口分析

汽车之家车型参数对比采用前后端分离 + 动态渲染架构,核心数据通过 API 接口返回,而非直接嵌入 HTML。

(1)核心接口定位

打开汽车之家车型对比页(如https://car.autohome.com.cn/config/series/45678.html),按 F12 打开开发者工具,切换到「Network」→「XHR」,刷新页面后可定位到参数数据接口:

  • 基础参数接口:https://www.autohome.com.cn/ashx/car/GetConfigNew.ashx?type=base&specid=车型ID
  • 配置参数接口:https://www.autohome.com.cn/ashx/car/GetConfigNew.ashx?type=config&specid=车型ID
  • 车型列表接口:https://www.autohome.com.cn/ashx/car/getseries.ashx?type=1&value=品牌ID
(2)关键参数说明
  • specid:车型唯一标识 ID,是获取参数的核心参数
  • type:区分基础参数(base)与配置参数(config)
  • 响应格式:JSON,包含车型名称、长宽高、动力、安全配置等全量参数

3. 反爬机制与应对策略

汽车之家反爬体系完善,需针对性破解才能稳定爬取:

表格

反爬类型 表现形式 应对方案
IP 封禁 高频请求触发 403/503 错误 代理 IP 轮换、控制请求频率(1-3 秒 / 次)
User-Agent 校验 无 UA 或异常 UA 被拦截 随机 UA 池,模拟真实浏览器标识
字体反爬 价格 / 参数用自定义字体显示为乱码 解析字体文件,建立字符映射表
验证码拦截 访问过快弹出图形验证码 降低请求频率,必要时接入打码平台

二、完整爬取代码实现

1. 基础配置与工具函数

python

运行

复制代码
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import random
from fake_useragent import UserAgent

# 初始化UA池
ua = UserAgent()
# 请求延时(避免触发反爬)
DELAY = random.uniform(1, 3)
# 基础请求头
BASE_HEADERS = {
    "Referer": "https://car.autohome.com.cn/",
    "Accept": "application/json, text/javascript, */*; q=0.01",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Origin": "https://car.autohome.com.cn"
}

# 随机生成请求头
def get_headers():
    headers = BASE_HEADERS.copy()
    headers["User-Agent"] = ua.random
    return headers

# 发送请求(含异常处理)
def send_request(url, retries=3):
    for _ in range(retries):
        try:
            response = requests.get(url, headers=get_headers(), timeout=10)
            response.raise_for_status()
            return response.json() if "json" in response.headers.get("Content-Type", "") else response.text
        except Exception as e:
            print(f"请求失败,重试中:{e}")
            time.sleep(DELAY)
    print(f"请求失败,已达最大重试次数:{url}")
    return None

2. 获取车型 ID(核心前置步骤)

车型 ID 是爬取参数的关键,需先从品牌列表页提取:

python

运行

复制代码
# 获取指定品牌的所有车型ID
def get_model_ids(brand_id):
    api_url = f"https://www.autohome.com.cn/ashx/car/getseries.ashx?type=1&value={brand_id}"
    data = send_request(api_url)
    model_ids = []
    if data and data.get("result") and data["result"].get("serieslist"):
        for series in data["result"]["serieslist"]:
            model_ids.append({
                "model_id": series["id"],
                "model_name": series["name"],
                "brand_name": series["brandname"]
            })
    return model_ids

# 示例:获取奥迪(品牌ID:3170)的所有车型ID
audi_models = get_model_ids(3170)
print(f"奥迪车型数量:{len(audi_models)}")

3. 爬取车型参数并生成对比表

python

运行

复制代码
# 爬取单个车型的基础+配置参数
def scrape_model_params(model_id, model_name):
    # 基础参数
    base_url = f"https://www.autohome.com.cn/ashx/car/GetConfigNew.ashx?type=base&specid={model_id}"
    base_data = send_request(base_url)
    # 配置参数
    config_url = f"https://www.autohome.com.cn/ashx/car/GetConfigNew.ashx?type=config&specid={model_id}"
    config_data = send_request(config_url)
    
    if not base_data or not config_data:
        return None
    
    # 提取核心参数(可根据需求扩展)
    params = {
        "车型名称": model_name,
        "厂商": base_data.get("carbrand", ""),
        "级别": base_data.get("levelname", ""),
        "能源类型": base_data.get("fueltypename", ""),
        "长*宽*高(mm)": base_data.get("size", ""),
        "轴距(mm)": base_data.get("wheelbase", ""),
        "发动机型号": base_data.get("enginename", ""),
        "最大功率(kW)": base_data.get("maxpower", ""),
        "最大扭矩(N·m)": base_data.get("maxtorque", ""),
        "变速箱": base_data.get("gearbox", ""),
        "驱动方式": base_data.get("drivetype", ""),
        "安全配置": "、".join([item["name"] for item in config_data.get("safebag", [])]),
        "辅助配置": "、".join([item["name"] for item in config_data.get("assist", [])])
    }
    return params

# 批量爬取并生成对比表
def generate_comparison_table(brand_models):
    all_params = []
    for model in brand_models:
        print(f"正在爬取:{model['model_name']}")
        params = scrape_model_params(model["model_id"], model["model_name"])
        if params:
            all_params.append(params)
        time.sleep(DELAY)
    
    # 生成DataFrame并导出
    df = pd.DataFrame(all_params)
    df.to_csv("汽车之家车型参数对比表.csv", index=False, encoding="utf_8_sig")
    df.to_excel("汽车之家车型参数对比表.xlsx", index=False)
    print("参数对比表生成完成!")
    return df

# 执行批量爬取
if audi_models:
    comparison_df = generate_comparison_table(audi_models)
    print(comparison_df.head())

三、代码优化与进阶技巧

1. 代理 IP 集成(应对 IP 封禁)

python

运行

复制代码
# 代理IP池(示例,实际需使用稳定代理)
PROXY_POOL = [
    {"http": "http://112.85.160.10:8080", "https": "http://112.85.160.10:8080"},
    {"http": "http://115.223.201.5:3128", "https": "http://115.223.201.5:3128"}
]

# 修改send_request函数,添加代理
def send_request(url, retries=3):
    for _ in range(retries):
        try:
            proxy = random.choice(PROXY_POOL)
            response = requests.get(url, headers=get_headers(), proxies=proxy, timeout=10)
            response.raise_for_status()
            return response.json() if "json" in response.headers.get("Content-Type", "") else response.text
        except Exception as e:
            print(f"请求失败,重试中:{e}")
            time.sleep(DELAY)
    return None

2. 字体反爬破解(解决参数乱码)

汽车之家部分参数(如价格)采用自定义字体,需解析字体文件建立映射:

python

运行

复制代码
import re
from fontTools.ttLib import TTFont

# 解析字体文件,生成字符映射表
def parse_font(font_url):
    response = requests.get(font_url, headers=get_headers())
    with open("temp.woff", "wb") as f:
        f.write(response.content)
    font = TTFont("temp.woff")
    # 提取字符映射(需根据实际字体调整)
    cmap = font.getBestCmap()
    char_map = {chr(k): v for k, v in cmap.items() if k > 128}
    return char_map

# 替换乱码参数
def replace_garbled(text, char_map):
    for garbled, real in char_map.items():
        text = text.replace(garbled, real)
    return text

3. 增量爬取(避免重复采集)

使用 Redis 存储已爬取的车型 ID,实现增量更新:

python

运行

复制代码
import redis

# 连接Redis
r = redis.Redis(host="localhost", port=6379, db=0)

# 增量爬取判断
def is_scraped(model_id):
    return r.sismember("scraped_model_ids", model_id)

def mark_scraped(model_id):
    r.sadd("scraped_model_ids", model_id)

# 修改批量爬取逻辑
def generate_comparison_table(brand_models):
    all_params = []
    for model in brand_models:
        if is_scraped(model["model_id"]):
            print(f"{model['model_name']} 已爬取,跳过")
            continue
        params = scrape_model_params(model["model_id"], model["model_name"])
        if params:
            all_params.append(params)
            mark_scraped(model["model_id"])
        time.sleep(DELAY)
    # 导出数据...

四、法律与道德规范

爬取数据需遵守以下规则,避免法律风险:

  1. 遵守robots.txt协议:汽车之家robots.txt禁止爬取部分敏感页面,需严格遵循
  2. 控制请求频率:避免高频请求导致服务器压力,设置合理延时
  3. 数据使用合规:仅用于个人学习、研究,不得用于商业用途或非法传播
  4. 尊重版权:汽车之家数据受版权保护,爬取后不得擅自二次分发

五、总结

本文通过 Python 实现了汽车之家车型参数对比表的自动化爬取,从接口分析、反爬应对到代码落地,覆盖了完整的爬虫流程。通过代理 IP、字体反爬破解、增量爬取等优化,可实现稳定、高效的数据采集。

相关推荐
青 春 记 忆7 小时前
Dify Docker Compose 通用无损升级指南:从备份、双版本预演到切换与回滚
运维·人工智能·python·docker·容器
GlueNa2SiO37 小时前
03-Flask模板引擎Jinja2详解
笔记·python·flask
临沂GEO10 小时前
GEO搜索优化科普|正规地理位置流量运营入门指南
大数据·人工智能·python·流量运营
大模型码小白10 小时前
Spring AI Tool 实现自然语言操作 MySQL 数据库详解
服务器·开发语言·数据库·人工智能·python·mysql·spring
深蓝电商API11 小时前
常见反爬策略全解析
爬虫·反爬策略
荷蒲11 小时前
【小白量化Qbuddy】利用AI学习中文Python
人工智能·python·学习
数据狐(Datafox)13 小时前
京东商品列表API技术解析与落地应用(含标准 JSON 示例)
java·大数据·前端·人工智能·python·数据分析·json
量化吞吐机13 小时前
2026年下半年手工交易规则走向量化表达,产品该先接住哪一步
人工智能·python
Metaphor69214 小时前
使用 Python 读取和删除 Excel 文件属性
python·excel
迷迭香yy14 小时前
Python构建转融券多空识别系统从接口到因子的全流程 IG50免费开源股票数据API接口
开发语言·python·开源