scrapy爬取汽车、车评数据【上】

这个爬虫我想分三期来写:
✅ 第一期写如何爬取汽车的车型信息;
✅ 第二期写如何爬取汽车的车评;
✅ 第三期写如何对车评嵌入情感分析结果,以及用简单的方法把数据插入mysql中;
技术基于scrapy框架、BERT语言模型、mysql数据库。

1 新建工程

scrapy的老三样,可以用命令创建工程

scrapy startproject car_spider

进入目录,创建爬虫

cd car_spider
scrapy genspider car dongchedi.com

这样scrapy就自动搭好了看框架,然后用开发工具打开就行了。

2 分页爬取车型

我们的爬取思路是先根据车型接口获取到所有的车型,然后根据汽车的详情接口去获取汽车详情数据。
获取车型的接口是post请求,带有分页参数的,所以可以这么处理:

class CarSpider(scrapy.Spider):
    name = 'car'
    allowed_domains = ['dongchedi.com']
    start_url = 'https://www.dongchedi.com/motor/pc/car/brand/select_series_v2?aid=1839&app_name=auto_web_pc'

    custom_settings = {
        'USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 '
                      '(KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
    }

    def __init__(self, *args, **kwargs):
        super(CarSpider, self).__init__(*args, **kwargs)
        self.item_count = 0  # 初始化计数器
        self.limit = 20  # 每页数据量
        self.current_page = 1  # 当前页码

    def start_requests(self):
        """首次发送 POST 请求"""
        formdata = {
            'page': str(self.current_page),
            'limit': str(self.limit),
        }
        yield scrapy.FormRequest(
            url=self.start_url,
            formdata=formdata,
            callback=self.parse
        )
    def parse(self, response):
        """解析分页数据并提取信息"""
        data = json.loads(response.body)
        series_list = data['data']['series']
        series_count = data['data']['series_count']  # 总数据量
        total_pages = (series_count // self.limit) + 1  # 计算总页数

        # 处理当前页的数据
        for car in series_list:
            car_id = car['concern_id']
            detail_url = f'https://www.dongchedi.com/motor/car_page/m/v1/series_all_json/?series_id={car_id}&city_name=武汉&show_city_price=1&m_station_dealer_price_v=1'
            yield scrapy.Request(url=detail_url, callback=self.parse_detail)

        # 如果还有下一页,继续发送请求
        if self.current_page < total_pages:
            self.current_page += 1
            formdata = {
                'page': str(self.current_page),
                'limit': str(self.limit),
            }
            yield scrapy.FormRequest(
                url=self.start_url,
                formdata=formdata,
                callback=self.parse
            )

3 爬取车型详细信息

获取到car[‘concern_id’]之后,就根据这个利用parse_detail去处理详情信息,获取到之后传给Item、pipeline

 def parse_detail(self, response):
        """解析汽车详细信息"""
        data = json.loads(response.body)
        series_all = data.get('data', {})
        cover_img = series_all.get('cover_url')
        brand_name = series_all.get('brand_name')
        series_id = series_all.get('series_id')
        online_models = series_all.get('online', [])

        for model in online_models:
            model_info = model['info']
            try:
                series_name = model_info['name']
                car_name = model_info['series_name']
                price_info = model_info['price_info']
                dealer_price = price_info.get('official_price', 'N/A')
                car_id = model_info.get('car_id')
                owner_price_summary = model_info.get('owner_price_summary', {})
                naked_price_avg = owner_price_summary.get('naked_price_avg', 'N/A')

                # 创建Item实例
                item = DongchediItem()
                item['name'] = f"{car_name}-{series_name}"
                item['dealer_price'] = dealer_price
                item['naked_price_avg'] = naked_price_avg
                item['brand_name'] = brand_name
                item['cover_img'] = cover_img
                item['series_id'] = series_id
                item['car_id'] = car_id
                self.item_count += 1  # 增加计数器
                # 返回item,保存到数据库或文件
                yield item

4 爬取结束给出统计信息

爬虫结束后给出统计信息,看看爬取了多少个数据,这里用紫色的字体:

    def closed(self, reason):
        """爬虫结束时调用"""
        purple_text = f"\033[95m总共爬取了 {self.item_count} 个 item\033[0m"
        self.logger.info(purple_text)

5 items 和 pipeline

实际上这个接口可以获取非常多的信息,这边写的比较简单,pipeline的处理也省略了,就进行一个打印:
items


class DongchediItem(scrapy.Item):
    name = scrapy.Field()
    dealer_price = scrapy.Field()
    naked_price_avg = scrapy.Field()
    brand_name = scrapy.Field()
    cover_img = scrapy.Field()
    series_id = scrapy.Field()
    car_id = scrapy.Field()

pipelines,注意在settings.py里激活一下

class DongchediPipeline:
    def process_item(self, item, spider):
        # 可以添加保存数据库或文件的逻辑
        print(item)
        return item

5 运行结果

运行一圈,发现爬取到了12565个车的数据。
在这里插入图片描述

Scrapy是一个用于抓取网页内容并提取结构化数据的强大框架,它非常适合用来爬取汽车销售数据等信息。下面是关于如何利用Scrapy框架来进行这一任务的一些关键步骤和注意事项: ### 准备工作 1. **安装依赖**:首先需要确保已经安装了Python环境,并通过pip工具安装scrapy库。 ```bash pip install scrapy ``` 2. **创建项目**: 使用命令行创建一个新的Scrapy项目,在此项目中可以定义spider来指定要访问的目标网站及其解析规则。 ```bash scrapy startproject carsales_data_collection cd carsales_data_collection ``` ### 设计Spider 接下来就是设计具体的spiders去完成实际的数据采集任务。针对汽车销售相关的页面,你需要考虑以下几个方面: - 确定目标URL模式以及分页机制; - 分析HTML文档结构找到所需字段所在位置(XPath/CSS选择器); - 对于反爬虫策略(如验证码、IP限制),寻找绕过的方法或等待时间间隔设置合理请求头等; 假设我们要从某知名二手车交易平台获取车辆基本信息(品牌型号,价格里程数),那么可以在`carsales.py`文件下编写如下代码片段作为示例: ```python import scrapy class CarSalesSpider(scrapy.Spider): name = "car_sales" allowed_domains = ["example.com"] # 替换为目标站点域名 def start_requests(self): urls = [ 'http://www.example.com/cars?page=1', ] for url in urls: yield scrapy.Request(url=url,callback=self.parse) def parse(self,response): items=response.xpath('//div[@class="item-container"]')# 根据实际情况调整 for item in items: car={ 'brand': item.css('span.brand::text').get(), 'model': item.css('span.model::text').get(), 'price': item.css('p.price strong::text').re(r'\d+,\d+'), 'mileage': item.re('<li>Mileage: (.*) km</li>')[0] } self.log(f"Extracted data {car}") if __name__ == "__main__": from scrapy.crawler import CrawlerProcess process=CrawlerProcess() process.crawl(CarSalesSpider) process.start() ``` 上面的例子仅作为一个简单参考模板,具体实现还需要根据所选平台的具体情况进行修改和完善。此外需要注意的是合法性和道德规范的问题——始终遵守robots.txt协议并且不要对服务器造成过大压力!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

麦麦大数据

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

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

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

打赏作者

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

抵扣说明:

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

余额充值