Scrapy 分布式爬虫:大规模采集汽车之家电车评论

作者:小白学大数据日期:2026/5/5

汽车之家电车评论包含车型体验、续航表现等关键信息,是产品分析与市场调研的核心数据源。单台机器运行Scrapy爬虫易触发反爬、效率低下,分布式爬虫通过多机器协同,可有效解决这一问题。本文将精简讲解Scrapy分布式爬虫的搭建、配置、开发及部署,附带完整可运行代码,助力开发者快速实现大规模评论采集。

一、核心技术栈与环境准备

搭建Scrapy分布式爬虫需多组件协同,核心配置如下:

1.1 核心技术选型

  • Scrapy:核心爬虫框架,负责请求、解析与调度,支持中间件扩展。
  • Scrapy-Redis:分布式核心,替代本地调度器,实现多机器任务共享与去重。
  • Redis:存储待爬URL、去重集合,支持高并发访问。
  • Python 3.8+:确保依赖兼容性;MySQL:结构化存储评论数据。
  • 亿牛云代理www.16yun.cn):动态切换IP,规避反爬封禁。

1.2 环境搭建步骤

  1. 安装依赖pip install scrapy scrapy-redis redis pymysql requests
  2. Redis配置:安装后修改redis.conf,注释bind 127.0.0.1、关闭protected-mode no,允许分布式节点访问。
  3. MySQL准备:创建数据库和表,SQL语句如下: CREATE DATABASE IF NOT EXISTS car_home_ev;USE car_home_ev;CREATE TABLE IF NOT EXISTS ev_comments (id INT PRIMARY KEY AUTO_INCREMENT,car_model VARCHAR(50) NOT NULL,user_name VARCHAR(30),comment_time VARCHAR(20),comment_content TEXT NOT NULL,score INT,mileage VARCHAR(20),crawl_time DATETIME DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  4. 代理配置:注册亿牛云代理,获取服务器地址、账号密码备用。

二、Scrapy分布式爬虫核心原理

传统Scrapy爬虫数据存储于单台机器内存,无法协同。Scrapy-Redis重写调度器与去重器,将核心数据存入Redis,实现多机器共享任务:

  1. 任一节点启动爬虫,将初始URL存入Redis待爬队列(scrapy:requests)。
  2. 所有节点连接Redis,获取URL执行爬取,解析数据与新URL。
  3. 新URL经Redis去重(scrapy:dupefilter)后加入队列,数据存入MySQL。
  4. 待爬队列为空时,爬虫终止,单节点故障不影响整体任务。

三、实战开发:Scrapy分布式爬虫搭建(附代码)

以下代码可直接复制运行,仅需修改代理、数据库等个人配置。

3.1 创建项目与分布式配置

3.1.1 创建项目
1# 创建项目
2scrapy startproject car_home_ev_spider
3cd car_home_ev_spider
4# 创建爬虫(指定域名)
5scrapy genspider ev_comment autohome.com.cn
6
3.1.2 settings.py核心配置
1# -*- coding: utf-8 -*-
2BOT_NAME = 'car_home_ev_spider'
3SPIDER_MODULES = ['car_home_ev_spider.spiders']
4NEWSPIDER_MODULE = 'car_home_ev_spider.spiders'
5
6ROBOTSTXT_OBEY = False  # 关闭robots协议
7# 分布式核心配置
8SCHEDULER = "scrapy_redis.scheduler.Scheduler"
9DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
10REDIS_URL = 'redis://192.168.1.100:6379/0'  # 替换自身Redis地址
11SCHEDULER_PERSIST = False
12SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
13
14# 反爬与请求配置
15DEFAULT_REQUEST_HEADERS = {
16    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
17    'Accept-Language': 'zh-CN,zh;q=0.9',
18    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
19    'Referer': 'https://www.autohome.com.cn/',
20    'Cookie': '填写自身汽车之家Cookie'
21}
22DOWNLOAD_DELAY = 1.5
23CONCURRENT_REQUESTS = 16
24
25# 代理与数据库配置
26PROXY_URL = 'http://www.16yun.cn:8080'
27PROXY_USER = '你的代理用户名'
28PROXY_PASS = '你的代理密码'
29MYSQL_HOST = 'localhost'
30MYSQL_USER = 'root'
31MYSQL_PASSWORD = '你的MySQL密码'
32MYSQL_DB = 'car_home_ev'
33MYSQL_PORT = 3306
34
35# 启用Pipeline
36ITEM_PIPELINES = {
37    'car_home_ev_spider.pipelines.CarHomeEvSpiderPipeline': 300,
38}
39LOG_LEVEL = 'INFO'
40LOG_FILE = 'car_home_ev.log'
41

3.2 数据模型(items.py)

1# -*- coding: utf-8 -*-
2import scrapy
3
4class CarHomeEvSpiderItem(scrapy.Item):
5    car_model = scrapy.Field()  # 车型
6    user_name = scrapy.Field()  # 用户名
7    comment_time = scrapy.Field()  # 评论时间
8    comment_content = scrapy.Field()  # 评论内容
9    score = scrapy.Field()  # 评分
10    mileage = scrapy.Field()  # 行驶里程
11    crawl_time = scrapy.Field()  # 爬取时间
12

3.3 代理中间件(middlewares.py)

1# -*- coding: utf-8 -*-
2import base64
3from scrapy import signals
4from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware
5from car_home_ev_spider.settings import PROXY_URL, PROXY_USER, PROXY_PASS
6
7class CarHomeEvSpiderMiddleware:
8    @classmethod
9    def from_crawler(cls, crawler):
10        s = cls()
11        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
12        return s
13    def spider_opened(self, spider):
14        spider.logger.info('Spider opened: %s' % spider.name)
15
16# 亿牛云代理中间件
17class ProxyMiddleware(HttpProxyMiddleware):
18    def __init__(self, auth_encoding='latin-1'):
19        self.auth_encoding = auth_encoding
20        self.proxy_auth = base64.b64encode(f"{PROXY_USER}:{PROXY_PASS}".encode(self.auth_encoding)).decode(self.auth_encoding)
21    def process_request(self, request, spider):
22        request.meta['proxy'] = PROXY_URL
23        request.headers['Proxy-Authorization'] = f'Basic {self.proxy_auth}'
24
25# 反反爬中间件
26class AntiAntiCrawlMiddleware:
27    def process_request(self, request, spider):
28        request.headers['Cookie'] = spider.settings.get('DEFAULT_REQUEST_HEADERS')['Cookie']
29        return None
30

在settings.py中添加中间件配置:

1DOWNLOADER_MIDDLEWARES = {
2    'car_home_ev_spider.middlewares.ProxyMiddleware': 543,
3    'car_home_ev_spider.middlewares.AntiAntiCrawlMiddleware': 544,
4    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None,
5}
6

3.4 核心爬虫(ev_comment.py)

1# -*- coding: utf-8 -*-
2import scrapy
3from car_home_ev_spider.items import CarHomeEvSpiderItem
4
5class EvCommentSpider(scrapy.Spider):
6    name = 'ev_comment'
7    allowed_domains = ['autohome.com.cn']
8    start_urls = ['https://www.autohome.com.cn/electric/']  # 电车列表页
9
10    def parse(self, response):
11        # 解析车型列表,获取评论页URL
12        car_list = response.xpath('//div[@class="list-cont"]/div[@class="cont-box"]')
13        for car in car_list:
14            car_model = car.xpath('.//h3/a/text()').extract_first().strip()
15            comment_url = car.xpath('.//div[@class="btn-box"]/a[contains(text(), "口碑")]/@href').extract_first()
16            if comment_url:
17                yield scrapy.Request(
18                    url=response.urljoin(comment_url),
19                    callback=self.parse_comment_list,
20                    meta={'car_model': car_model},
21                    dont_filter=True
22                )
23        # 列表页分页
24        next_page = response.xpath('//a[@class="page-item-next"]/@href').extract_first()
25        if next_page:
26            yield scrapy.Request(url=response.urljoin(next_page), callback=self.parse, dont_filter=True)
27
28    def parse_comment_list(self, response):
29        # 解析评论数据
30        car_model = response.meta['car_model']
31        comment_list = response.xpath('//div[@class="koubei-list"]/div[@class="koubei-item"]')
32        for comment in comment_list:
33            item = CarHomeEvSpiderItem()
34            item['car_model'] = car_model
35            item['user_name'] = comment.xpath('.//div[@class="user-info"]/a/text()').extract_first() or '未知用户'
36            item['comment_time'] = comment.xpath('.//div[@class="user-info"]/span/text()').extract_first() or ''
37            comment_content = comment.xpath('.//div[@class="content"]/p/text()').extract()
38            item['comment_content'] = ''.join([text.strip() for text in comment_content]) if comment_content else ''
39            score_class = comment.xpath('.//div[@class="score"]/span/@class').extract_first()
40            item['score'] = int(score_class.replace('star', '')) if score_class else None
41            item['mileage'] = comment.xpath('.//div[@class="info"]/span[1]/text()').extract_first().strip() if comment.xpath('.//div[@class="info"]/span[1]/text()').extract_first() else '未知'
42            item['crawl_time'] = None
43            yield item
44        # 评论页分页
45        next_comment_page = response.xpath('//a[@class="page-next"]/@href').extract_first()
46        if next_comment_page:
47            yield scrapy.Request(
48                url=response.urljoin(next_comment_page),
49                callback=self.parse_comment_list,
50                meta={'car_model': car_model},
51                dont_filter=True
52            )
53

3.5 数据存储Pipeline(pipelines.py)

1# -*- coding: utf-8 -*-
2import pymysql
3from datetime import datetime
4from car_home_ev_spider.settings import MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB, MYSQL_PORT
5
6class CarHomeEvSpiderPipeline:
7    def __init__(self):
8        # 初始化数据库连接
9        self.conn = pymysql.connect(
10            host=MYSQL_HOST, user=MYSQL_USER, password=MYSQL_PASSWORD,
11            database=MYSQL_DB, port=MYSQL_PORT, charset='utf8mb4'
12        )
13        self.cursor = self.conn.cursor()
14
15    def process_item(self, item, spider):
16        item['crawl_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
17        # 插入数据,避免重复
18        sql = """
19        INSERT INTO ev_comments (car_model, user_name, comment_time, comment_content, score, mileage, crawl_time)
20        VALUES (%s, %s, %s, %s, %s, %s, %s)
21        ON DUPLICATE KEY UPDATE comment_time = VALUES(comment_time), score = VALUES(score)
22        """
23        try:
24            self.cursor.execute(sql, (item['car_model'], item['user_name'], item['comment_time'],
25                                      item['comment_content'], item['score'], item['mileage'], item['crawl_time']))
26            self.conn.commit()
27        except Exception as e:
28            self.conn.rollback()
29            spider.logger.error(f"插入失败:{str(e)}")
30        return item
31
32    def close_spider(self, spider):
33        self.cursor.close()
34        self.conn.close()
35

四、分布式部署与运行

4.1 节点准备

多台机器需与Redis服务器同局域网,安装相同环境,复制项目并确保所有节点REDIS_URL、代理、数据库配置一致。

4.2 启动步骤

  1. 启动Redis服务,通过redis-cli ping测试连接。
  2. 各节点进入项目目录,执行scrapy crawl ev_comment启动爬虫。
  3. 通过redis-cli keys *查看任务队列,通过MySQL查询实时查看爬取数据。

五、反爬应对与优化

  • 控制请求频率,调整DOWNLOAD_DELAY,节点数量控制在5-10台。
  • 定期更新Cookie,及时适配汽车之家页面变化,调整XPath表达式。
  • 增加异常捕获与重试机制,通过日志排查问题,可实现增量爬取减少重复工作。

六、总结与扩展

本文实现了Scrapy分布式爬虫采集汽车之家电车评论,解决了单机器爬取效率低、易反爬的问题。后续可扩展情感分析、数据可视化、定时爬取等功能,适配多汽车平台,进一步提升数据价值。分布式爬虫的核心是协同高效,需根据反爬强度灵活调整策略,确保稳定采集。


Scrapy 分布式爬虫:大规模采集汽车之家电车评论》 是转载文章,点击查看原文


相关推荐


散户如何使用手机T0算法?
韭菜修养2026/4/25

1、什么是T0算法?T0算法如何运作? 据记者了解,当前多家券商已在其APP中推出T0算法服务,旨在通过智能化交易工具帮助投资者捕捉日内波动收益,执行“低买高卖”策略,帮助投资者降低持仓成本或增厚收益。 T0算法,全称“日内交易算法”,是一种基于量化模型的自动化交易工具。其核心逻辑是通过实时分析市场数据(如价格、成交量、盘口信息等),在极短时间内捕捉股票日内波动产生的价差,执行“低买高卖”操作,从而帮助投资者降低持仓成本或增厚收益。   具体来说,算法会设定一系列的规则和指标,当市场价


深度解密 Rollup 插件开发:核心钩子函数全生命周期图鉴
发现一只大呆瓜2026/4/17

前言 Rollup 的强大在于其精简的插件系统。一个 Rollup 插件本质上就是一个包含各种“钩子函数”的对象。理解这些钩子的执行时序,是编写高性能插件、优化构建流程的关键。本文将带你深度复盘 Rollup 的两大核心阶段:构建 (Build) 与 输出 (Output) 。 一、构建阶段钩子函数(核心阶段) 构建阶段主要负责模块的解析、加载和转换,最终完成模块依赖图的构建,是Rollup打包的基础。该阶段可细分为5个小阶段,钩子执行顺序固定为: 初始化阶段(options、buildSta


记一次 OKE 集群上的 TCP 流量黑洞排查与解决全过程
小猿姐2026/4/9

作为 Apecloud 团队,我们致力于通过开源的 KubeBlocks 项目,在 Kubernetes (K8s) 上为用户提供企业级的数据库高可用方案[1]。其中,SQL Server on K8s with Always On 是我们支持的关键能力之一,相比Microsoft 为在容器中运行 SQL Server 提供的基础StatefulSet方案, KubeBlocks 的 MSSQL Addon 提供了一整套生产级的生命周期管理能力,包括:多节点高可用配置、动态扩缩容、数据库/账户管


Spring Boot 牵手Spring AI,玩转DeepSeek大模型
小码哥_常2026/4/1

Spring Boot 牵手Spring AI,玩转DeepSeek大模型 引言:开启 AI 集成之旅 在当今这个 AI 技术迅猛发展的时代,你是否想过如何将强大的大模型融入到我们日常的 Java 开发中,为应用赋予智能交互的能力呢?今天,我们就来探索如何通过 Spring Boot 集成 Spring AI,进而调用 DeepSeek 大模型,为你的项目注入全新的 AI 活力。这不仅能让你深入了解 AI 与后端开发融合的前沿技术,还能为你在实际项目中运用 AI 技术提供宝贵的经验 。接下来,就


OpenClaw实战|从识图到公众号内容自动化,我跑通了完整链路
后端小肥肠2026/3/23

大家好,我是小肥肠。今天这篇文章,想跟大家分享一下我最近刚跑通两个skill:让 OpenClaw图像理解和 飞书 文章一键转存至公众号草稿箱。 1. 前言 最近我在慢慢做一件事:把之前在 Coze 里折腾过的插件和工作流,陆续迁到 OpenClaw + Skill 这一套上。上周末我主要搞定了两件事,都已经不是“纸上谈兵”,是真的跑起来了。 第一件:把图像理解插件迁移成 OpenClaw Skill 我把之前做的图像理解Coze插件,迁成了一个独立的 xfc-img-understand sk


墨梅博客 1.9.0 发布与 LeanCloud 停服应对 | 2026 年第 11 周草梅周报
草梅友仁2026/3/15

本文在草梅友仁的博客发布和更新,并在多个平台同步发布。如有更新,以博客上的版本为准。您也可以通过文末的 原文链接 查看最新版本。 前言 欢迎来到草梅周报!这是一个由草梅友仁基于 AI 整理的周报,旨在为您提供最新的博客更新、GitHub 动态、个人动态和其他周刊文章推荐等内容。 开源动态 本周墨梅博客的开发依旧在稳步进行中。 您可以前往 Demo 站试用:demo.momei.app/ 您可以通过邮箱 admin@example.com,密码 momei123456 登录演示用管理员账号


ai-agent工程师指南
哈里谢顿2026/3/7

一些基本概念 1 Zero-shot & Few-shot 是什么? 1. Zero-shot(零样本) 不给例子,直接让模型做。 不提供任何参考样例 只告诉模型任务是什么 完全靠模型本身能力去理解、推理 例子 把下面句子分类成积极 / 消极:这部电影太好看了! 这就是 zero-shot。 2. Few-shot(少样本 / 小样本) 给几个例子,再让模型做。 给 1~10 个左右的示例 告诉模型:我要你像这样输出 模型照着格式、逻辑去做 例子 分类:今天心情很好 → 积极分类


CSDN创作变现活动!社区镜像或使用视频教程分别单个最高得 80 元,收益上不封顶!
CSDN官方博客2026/2/27

CSDN AI 社区是聚焦 AI 技术产业落地的开发者服务平台(官方入口),核心为创作者搭建技术价值转化桥梁,AI社区涵盖: 镜像市场(社区镜像)、算力市场等模块。 本次推出镜像创作激励活动,以下是方案活动规则、参与要求及激励政策,保障创作者权益与活动有序开展。 一、活动总则 活动时间: 2026年1月1日 - 2026年2月28日 现金奖励: 1、按照官方指定镜像任务创作,单个社区镜像奖励 30-80元现金 ,创作越多可获得现金奖


深度解析 JWT:从 RFC 原理到 NestJS 实战与架构权衡
NEXT062026/2/18

1. 引言 HTTP 协议本质上是无状态(Stateless)的。在早期的单体应用时代,为了识别用户身份,我们通常依赖 Session-Cookie 机制:服务端在内存或数据库中存储 Session 数据,客户端浏览器通过 Cookie 携带 Session ID。 然而,随着微服务架构和分布式系统的兴起,这种有状态(Stateful)的机制暴露出了明显的弊端:Session 数据需要在集群节点间同步(Session Sticky 或 Session Replication),这极大地限制了系统


RTOS核心三剑客:任务、信号量与队列深度解析
牛逍遥2026/2/9

RTOS核心三剑客:任务、信号量与队列深度解析 一、裸机编程的瓶颈:为什么需要RTOS? 在嵌入式开发中,裸机程序通常采用**超级循环(Super Loop)**结构: void main() { while(1) { read_sensors();// 读取传感器 process_data();// 处理数据 update_display();// 刷新显示 handle_uart();// 串口通信 check_safety();// 安全检测 } } 裸机编程的致命缺陷: 阻塞操作导致响

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客