爬取懂车帝所有品牌车型信息


 概要

本文将对懂车帝的所有品牌车辆车型数据进行爬取,包括:车型,价格,车辆配置等信息。

一、使用模块

import re
from typing import Dict, Optional

import requests
from bs4 import BeautifulSoup
from pymongo import MongoClient

二、反爬技术

1.js压缩和混淆

对代码进行压缩(去除空格,换行符)和混淆(无意义变量)降低可读性,格式化使得无法定位到数据的真实位置。

2.动态网页

动态网站通过JavaScript异步加载数据,需要查找数据接口,并且请求参数通常被加密参数保护。

三、分析过程

1.在选车页面,点击车型的参数,发现所有车型的数据,空白处右键,打开检查面板,选择网络选项卡,重新刷新网页,选取车名作为关键字进行搜索,发现数据嵌套在html,为静态网页。

观察请求的url,发现url中类似id的信息,以此作为思路,返回上一级查找。

2.返回上一级页面,通过昨天的内容,发现id确实是该车型的id,这样这个车型的信息就搞定了。但是后面发现,这样不利于信息的存储。于是我换了一个思路。先点开该车型的详细页面,再点击其中一个版本的参数详细。

经过以上步骤,我们成功获得了特定车型的数据页面,其中URL后面的数字猜测同样表示该车型的ID。结合第一天的内容,发现数据中存在一个名为car_ids的信息,经过验证,确认其与当前URL的ID对应。接下来,按照步骤1的分析过程进行数据提取,通过品牌ID、车型ID、版本ID以及参数信息组成一条数据,这样在后面进行SQL查询时更加方便和高效。

四、完整代码

import re
from typing import Dict, Optional

import requests
from bs4 import BeautifulSoup
from pymongo import MongoClient

# MongoDB 配置
MONGO_URI = "mongodb://localhost:27017/"
DB_NAME = "car_database"
COLLECTION_NAME = "car_info"

# 初始化 MongoDB 客户端
client = MongoClient(MONGO_URI)
db = client[DB_NAME]
collection = db[COLLECTION_NAME]

URL = 'https://www.dongchedi.com/motor/pc/car/brand/select_series_v2'
PARAMS = {
    'aid': 1839,
    'app_name': 'auto_web_pc'
}


def fetch_car_data(page: int) -> Optional[Dict]:
    """获取汽车数据"""
    data = {
        'sort_new': 'hot_desc',
        'city_name': '梅州',
        'limit': 30,
        'page': page
    }
    try:
        response = requests.post(URL, params=PARAMS, data=data, timeout=10)
        response.raise_for_status()
        return response.json()
    except requests.RequestException as e:
        print(f"请求第{page}页失败: {e}")
        return None


def extract_info(body_div):
    body_info = {}

    if body_div:
        config_block_name = body_div.find('h3', class_='cell_title__1COfA').text.strip()
        rows = body_div.find_all('div', class_='table_row__yVX1h')
        for row in rows:
            label = row.find('label', class_='cell_label__ZtXlw')
            value = row.find('div', class_='cell_normal__37nRi')
            if label and value:
                body_info[label.text.strip()] = value.text.strip()
        return {config_block_name: body_info}


def save_to_mongodb(car_data):
    """保存提取的数据到 MongoDB"""
    try:
        result = collection.insert_one(car_data)
        print(f"数据已保存,ID: {result.inserted_id}")
    except Exception as e:
        print(f"保存到 MongoDB 失败: {e}")


def main():
    car_data = fetch_car_data(1)
    if not car_data:
        return

    for car in car_data['data']['series']:
        car_info = {
            'brand_id': car['id'],
            "brand_name": car['brand_name'],
            "outter_name": car['outter_name'],
            "models": []
        }

        for car_id in car['car_ids']:
            response = requests.get(f'https://www.dongchedi.com/auto/params-carIds-{car_id}')
            if response.status_code != 200:
                print(f"请求失败: {response.status_code}")
                continue

            soup = BeautifulSoup(response.text, 'html.parser')
            car_name = soup.find('a', class_='cell_car__28WzZ').text.strip()
            car_price = soup.find('span', class_='cell_price__1jlTy').text.strip()

            # 提取配置信息
            config_info = []
            for item in soup.find_all('div', attrs={'name': re.compile(r'config-body-\d+')}):
                config = extract_info(item)
                if config:
                    config_info.append(config)

            # 构建汽车模型数据
            model_info = {
                "car_id": car_id,
                "car_name": car_name,
                "car_price": car_price,
                "configurations": config_info
            }
            car_info["models"].append(model_info)

        # 保存每个品牌的汽车信息到 MongoDB
        save_to_mongodb(car_info)


if __name__ == "__main__":
    main()

小结

有任何问题,欢迎评论。

### 使用 Python 编写爬虫抓取车型配置数据 为了实现这一目标,可以采用 `requests` 库发送 HTTP 请求并获取网页内容,再利用 `BeautifulSoup` 或者 `lxml` 解析 HTML 文档。对于 JSON 数据,则可以直接通过 `json` 模块处理。 #### 准备工作 首先需要安装必要的库: ```bash pip install requests beautifulsoup4 lxml jsonpath_ng ``` #### 抓取流程 定义 URL 和请求头信息以模拟浏览器访问行为[^1]: ```python import requests from bs4 import BeautifulSoup import json 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" } caks_url = 'https://www.dongchedi.com/auto/series/' ``` 构建函数用于获取特定 ID 的车型页面内容,并从中提取所需的信息片段: ```python def fetch_car_config(caks_id): url = caks_url + f'{caks_id}' response = requests.get(url=url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # 假设配置信息位于某个具有特定 class 属性的 div 中 config_divs = soup.find_all('div', {'class': 'config-class'}) configs = [] for div in config_divs: title = div.h3.string.strip() details = [item.text.strip() for item in div.ul.find_all('li')] configs.append({ 'title': title, 'details': details }) return configs ``` 如果 API 接口返回的是 JSON 格式的响应体,那么可以通过修改上述代码中的解析逻辑来适应这种情况[^2]: ```python response_json = response.json() # 提取出包含所有系列ID的部分 series_ids = response_json['data']['list'] for series_info in series_ids: current_series_id = series_info['series_id'] print(f'Processing Series ID: {current_series_id}') car_configs = fetch_car_config(current_series_id) with open(f'data/{current_series_id}.json', 'w') as file: json.dump(car_configs, file, ensure_ascii=False, indent=4) ``` 以上方法适用于静态加载的内容;如果是动态加载的数据(例如 AJAX 调用),则可能还需要进一步研究具体的网络请求模式以及参数设置方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值