使用 DrissionPage 批量抓取汽车之家车型及轮胎规格(含在售/停售)

本文分享一个实战项目,利用 DrissionPage 批量抓取汽车之家指定品牌的在售/停售车型及

其轮胎规格,并保存到 Excel,适合有 Python 基础、想做爬虫或数据采集的同学。代码详解、步骤分明、注释齐全,欢迎收藏点赞!


1. 背景说明

项目目标:
批量采集汽车之家指定品牌的所有在售/停售车型,并提取每个车型的轮胎规格(前轮/后轮)参数,最终整理到 Excel。

核心难点:

  • 汽车之家前端基于 JS 动态渲染,传统 requests/bs4 难以处理。

  • 车型、参数页面均为多层嵌套,页面结构复杂。

  • 需自动翻页,兼容无数据页终止抓取。

  • 需要支持多品牌批量采集。

为此,采用 DrissionPage 无头浏览器,实现页面跳转、点击、元素获取等复杂操作。


2. 环境准备

安装依赖:

pip install DrissionPage pandas

如遇环境/驱动配置问题,建议参见 DrissionPage 文档或官方仓库


3. 代码结构与核心流程

完整代码如下,下文会分章节详细讲解各部分实现:

from DrissionPage import Chromium, ChromiumOptions
import pandas as pd

brand_ids = [181, 275, 279, 283, 284, 294, 299, 309, 318, 319]  # 品牌ID可自由扩展
data_list = []

# 配置 ChromiumOptions 实例,设置为无头模式(后台运行不弹窗)
co = ChromiumOptions().headless()
page = Chromium(co)
tab = page.latest_tab

# ======== 以下为主采集流程 ==========
for brand_id in brand_ids:
    # 在售车型采集
    # ...省略(后续详细讲解)

    # 停售车型采集
    # ...省略(后续详细讲解)

# 保存结果
df = pd.DataFrame(data_list)
df.to_excel('car_specifications.xlsx', index=False)
page.quit()

4. 采集在售车型信息

抓取目标:
每个品牌的在售车型,提取品牌名、车型名、版本、前轮胎规格、后轮胎规格。

(1)分页采集,每页抓取车辆列表

每次请求类似
https://www.autohome.com.cn/price/brandid_{brand_id}/x-x-x-x-{page_num}

for brand_id in brand_ids:
    print(f'开始抓取品牌ID:{brand_id} 在售车辆...')
    page_num = 1
    while True:
        url = f'https://www.autohome.com.cn/price/brandid_{brand_id}/x-x-x-x-{page_num}'
        tab.get(url)
        # 获取当前页上的所有车辆(车辆主链接)
        cars = tab.eles(
            'xpath://*[@id="app"]/div/div[2]/div/div[2]/div[1]/div[2]/div[4]/div/div[1]/div/div[1]/div[1]/a[1]')
        if not cars:  # 无数据说明到底了
            print(f'品牌ID:{brand_id} 在售车辆 第 {page_num} 页 无数据,停止抓取')
            break

要点说明:

  • 利用 while True 循环自动翻页,cars 为空即停止。

  • 使用 XPath 精准定位到车辆主链接(部分页面结构复杂,不建议用 CSS 选择器)。

  • 每个品牌分多页抓取,无须担心漏车。


(2)打开车辆详情页,采集车型和参数页

进入每台车详情,抓取车型名参数页面链接

for car in cars:
    car_tab = car.click.for_new_tab()  # 新标签打开车型详情页
    title_ele = car_tab.ele('xpath://*[@id="series-info"]/div[1]/div[1]/div[2]')
    if title_ele:
        title = title_ele.text
    else:
        car_tab.close()
        continue
    # 获取参数页面链接(不同车型有不同结构,需兼容写法)
    param_link = (
        car_tab.ele('xpath://*[@id="series-info"]/div[2]/div[2]/div[2]/div[2]/div[2]/div[4]/a/span') or
        car_tab.ele('xpath://*[@id="series-info"]/div[2]/div[2]/div/div[2]/div[2]/div[4]/a/span')
    )
    if param_link:
        param_tab = param_link.click.for_new_tab()  # 再次打开参数页
        # ...参数页数据采集,见下节
        param_tab.close()
    car_tab.close()

要点说明:

  • .click.for_new_tab() 兼容性好,能避免原标签切换。

  • title 一般格式为品牌-车型,需后续分割提取。

  • param_link 结构多变,需兼容两种常见 XPath。


(3)采集版本/轮胎规格参数

进入参数页后,获取该车所有在售版本及对应轮胎参数:

series = param_tab.eles('xpath://*[@id="app"]/div[1]/div[1]/div[2]/div[2]/div/div[1]/div/a')  # 车型版本名
front_label = param_tab.ele('@text()=前轮胎规格')
front_wheels = front_label.parent().parent().eles('.style_col_sub__1tg7Z') if front_label else []
rear_label = param_tab.ele('@text()=后轮胎规格')
rear_wheels = rear_label.parent().parent().eles('.style_col_sub__1tg7Z') if rear_label else []
for idx, s in enumerate(series):
    series_name = s.text
    front_wheel = front_wheels[idx].text if idx < len(front_wheels) else "未找到"
    rear_wheel = rear_wheels[idx].text if idx < len(rear_wheels) else "未找到"
    brand_name = title.split('-')[0] if '-' in title else ''
    car_data = {
        '品牌': brand_name,
        '车型': title.split('-')[1] if '-' in title else title,
        '版本': series_name,
        '前轮规格': front_wheel,
        '后轮规格': rear_wheel
    }
    data_list.append(car_data)
    print(car_data)

要点说明:

  • series为该车型所有在售版本,对应每个参数。

  • 轮胎参数取法:先通过“前轮胎规格”定位参数块,再向上找父节点获取所有版本数据。

  • 多版本情况下,通过下标关联版本和轮胎参数。

  • 未找到参数时,填充“未找到”,保证后续数据完整。

  • 最终每辆车的每个版本都封装为字典追加到 data_list。


5. 采集停售车型(同理)

采集停售车型方法和在售基本一致,只是url 路径参数不同(区别在于 /x-1-x-x-),可复用全部采集逻辑:

print(f'开始抓取品牌ID:{brand_id} 停售车辆...')
page_num = 1
while True:
    url = f'https://www.autohome.com.cn/price/brandid_{brand_id}/x-1-x-x-{page_num}'
    tab.get(url)
    cars = tab.eles(
        'xpath://*[@id="app"]/div/div[2]/div/div[2]/div[1]/div[2]/div[4]/div/div[1]/div/div[1]/div[1]/a[1]')
    if not cars:
        print(f'品牌ID:{brand_id} 停售车辆 第 {page_num} 页 无数据,停止抓取')
        break
    # 采集逻辑同在售
    for car in cars:
        # ...省略,同上

6. 数据整理与保存

全部数据采集完后,使用 pandas 存为 Excel 表:

df = pd.DataFrame(data_list)
df.to_excel('car_specifications.xlsx', index=False)
page.quit()

要点说明:

  • 建议采集完成后再整体写 Excel,提升效率。

  • 每条数据结构固定:品牌、车型、版本、前轮规格、后轮规格。

  • 记得关闭 browser,释放系统资源。


7. 实用建议与易错点

  1. 动态页面结构易变:如果发现采集不到数据,需用 F12 检查 XPath 是否有变化。

  2. 批量抓取速度控制:如遇到被封、数据加载慢,可适当恢复 sleep 延迟或加代理。

  3. 品牌 ID 获取:品牌 ID 可通过主页品牌下拉菜单抓包获得。

  4. 数据去重/校验:有些品牌、车型数据结构不一,建议采集后用 pandas 进行二次清洗。

  5. 内存与标签控制:极端情况下标签页太多会爆内存,建议优化标签关闭逻辑。


8. 总结

本文介绍了基于 DrissionPage 抓取汽车之家车型参数(含在售/停售)的完整流程与核心代码,并逐步剖析了动态采集、多层页面跳转、参数提取等关键实现。通过这种方式可以灵活批量抓取汽车之家海量车型信息,方便做后续数据分析、建模等应用。

有任何采集或 DrissionPage 的技术问题,欢迎评论区留言交流!


觉得有用麻烦点赞、关注、收藏一波,感谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Volcanoforever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值