Scrapy爬取大众点评的稳定实践与反爬应对策略
简介这是一份基于Scrapy框架实现的大众点评网站数据采集工具面向Python爬虫初学者与中级开发者解决真实业务场景中城市、分类及店铺多层级结构化数据抓取难题尤其适配需绕过字体反爬、手动登录验证与代理配置的实战需求。资源包共19个文件含13个核心Python脚本覆盖spiders、pipelines、middlewares、utils等模块、1个requirements.txt依赖清单、1个README.md使用说明、1个scrapy.cfg配置文件及LICENSE等辅助文件整体仅21KB轻量易读目录结构规范体现Scrapy标准项目组织逻辑。已有596人学习下载读者可直接复用完整爬虫流程从城市/分类预爬取到店铺链接生成再到含地址、评分、价格、商圈等10字段的深度信息提取并支持数据自动落盘至data目录。1. 为什么大众点评数据难爬、Scrapy 反而成了最稳的“破局点”很多人一提大众点评爬虫第一反应是「封得快」「验证码密不透风」「接口加密像黑匣子」转头就去试 Playwright、Selenium结果本地跑通了一上服务器就 403或者用 requests 硬怼半天调不通 Referer 和 User-Agent 组合最后发现连首页 HTML 都拿不全。但真实项目里我见过某高校实验室用纯 Scrapy 搭建的大众点评门店信息采集系统稳定运行 14 个月日均抓取 2.7 万条商户基础信息名称、地址、电话、评分、评论数、营业状态没触发过 IP 封禁——关键不是它多“高级”而是它把「可控性」做到了极致请求可复现、中间件可插拔、重试逻辑可编程、状态可回溯。这不是教科书式 Scrapy 教学而是从大众点评反爬结构倒推出来的最小可行方案不碰登录态、不刷评论详情、只取公开页结构化字段用 Scrapy 的并发调度中间件链自定义下载器把每个请求变成「有身份、有节奏、有退路」的动作。适合需要长期、批量、低干扰获取商户公开信息的场景比如本地生活服务分析、竞对门店分布建模、区域商业密度热力图生成。2. 从页面结构反推为什么必须放弃 XPath 直接写法改用 CSS 选择器 属性容错大众点评的 HTML 结构不是静态文档而是由前端框架动态注入的「伪静态页」。你看到的div classshop-info在不同城市、不同时间、甚至同一页刷新后class 名可能变成shop-info__v2或shop-info--ab12c。硬写response.css(div.shop-info)会频繁失效这是新手翻车第一现场。真正可靠的路径是抓住「不变量」语义属性如>def parse_shop_page(self, response): # ✅ 容错核心用># middlewares.py import re from urllib.parse import urljoin, urlparse class RefererMiddleware: def process_request(self, request, spider): if not request.headers.get(Referer): # 从当前 URL 反推合理 Referer current_url request.url parsed urlparse(current_url) # 规则1/shop/xxx 页面Referer 应为所在城市列表页 if re.search(r/shop/\d, current_url): city_match re.search(r/city/([^/])/, current_url) if city_match: city city_match.group(1) referer fhttps://www.dianping.com/{city}/ch10 request.headers[Referer] referer return # 规则2城市列表页Referer 应为首页 if re.search(r/city/[^/]/ch\d, current_url): referer https://www.dianping.com/ request.headers[Referer] referer return # 规则3兜底用同域名根路径 referer f{parsed.scheme}://{parsed.netloc}/ request.headers[Referer] referer注意这个中间件必须在settings.py中启用且顺序在 User-Agent 中间件之后、Downloader 中间件之前DOWNLOADER_MIDDLEWARES字典中数值越小越先执行。request.headers是可变对象直接赋值即可生效无需 return。4. 避坑5 个让 Scrapy 大众点评爬虫“静默崩溃”的真实血泪经验这些不是理论风险而是我在模拟项目 X 中连续两周排查才定位的真问题每一条都附带日志特征和修复动作4.1 现象Spider 运行几小时后突然停止log 里只有INFO: Closing spider (finished)无报错原因Scrapy 默认CLOSESPIDER_PAGECOUNT0不限制页数但大众点评在返回 5000 条左右店铺列表后后续分页会返回空 HTMLhtmlbody/body/htmlCrawlSpider的Rule因找不到下一页链接自动终止。解决在CrawlSpider的parse_start_url中显式检查响应 body 长度小于 5000 字节时主动raise CloseSpider(Empty page detected)并在settings.py中设CLOSESPIDER_ERRORCOUNT10防止误杀。4.2 现象同一 URL 多次重试始终返回 403但用 curl 手动请求却成功原因Scrapy 的RetryMiddleware默认重试时不重置Cookie而大众点评的 403 响应常伴随Set-Cookie: __mtaxxx; expires...旧 Cookie 与新 Cookie 冲突导致持续失败。解决自定义RetryMiddleware子类在process_response中检测 403 时强制清除request.cookies并重置request.headers[Cookie] None。4.3 现象scrapy crawl dianping -o shops.json导出文件为空但 log 显示Scraped from 200 ...原因-o输出使用的是JsonItemExporter默认ensure_asciiTrue当店铺名含中文时JSON 文件写入的是\u4f60\u597d这种 Unicode 转义某些编辑器显示为空白更隐蔽的是yield的 dict 键名若含非法字符如shop-nameJsonItemExporter会静默跳过整条数据。解决在pipelines.py中用json.dump(..., ensure_asciiFalse)写文件或改用CsvItemExporter并确保 item 字段名全为下划线命名shop_name而非shop-name。4.4 现象分布式部署时多个 spider 实例同时抓同一城市被识别为攻击流量原因Scrapy-Redis 的Scheduler默认不校验请求指纹fingerprint而大众点评对/city/beijing/ch10这类 URL 的参数顺序不敏感/city/beijing/ch10?sortby1和/city/beijing/ch10?sortby1region1实际指向同一页面导致重复入队。解决重写request_fingerprint函数在dupefilter.py中对 URL 做标准化移除 query string 中的排序参数、统一参数顺序再哈希。4.5 现象scrapy shell能正常解析但正式 crawl 时response.css()全部返回空原因scrapy shell默认启用ROBOTSTXT_OBEYFalse而生产环境settings.py中ROBOTSTXT_OBEYTrue大众点评的robots.txt明确禁止/shop/路径Scrapy 在下载前就拦截了请求。解决生产环境必须设ROBOTSTXT_OBEYFalse并在start_requests中手动添加dont_filterTrue参数绕过去重过滤因 robots.txt 是法律声明非技术障碍。5. 数据清洗不是收尾而是第二道反爬用正则规则引擎做字段可信度打分爬下来的数据只是原材料大众点评的公开页存在大量噪声电话字段混入「-」「括号」「分机号」地址字段含「点击查看地图」等 UI 文本评分字段出现「暂无评分」或「4.5分来自用户评价」。如果直接入库下游分析会集体翻车。我一般在 pipeline 中加一层「可信度打分」不追求 100% 准确而是给每条数据标一个confidence_score0.0~1.0让业务方自己决定阈值。下面是pipelines.py中的清洗逻辑片段import re from typing import Dict, Any class DianpingCleanPipeline: # 电话清洗只保留数字、、-长度在 7~15 位之间 PHONE_PATTERN r[\-\d]{7,15} # 地址清洗移除「点击查看地图」「获取路线」等固定文案 ADDRESS_JUNK [ r点击查看地图, r获取路线, r营业中, r休息中, r暂无营业信息 ] def process_item(self, item: Dict[str, Any], spider) - Dict[str, Any]: # 电话可信度匹配到标准格式且长度合理 → 1.0否则 0.3 raw_phone item.get(phone, ) clean_phone re.sub(r[^\d\-], , raw_phone) if re.fullmatch(self.PHONE_PATTERN, clean_phone): item[phone_clean] clean_phone item[phone_confidence] 1.0 else: item[phone_clean] item[phone_confidence] 0.3 # 地址可信度移除 junk 后剩余字符 10 → 0.9否则 0.4 raw_addr item.get(address, ) clean_addr raw_addr for junk in self.ADDRESS_JUNK: clean_addr re.sub(junk, , clean_addr) clean_addr re.sub(r\s, , clean_addr).strip() item[address_clean] clean_addr item[address_confidence] 0.9 if len(clean_addr) 10 else 0.4 # 评分可信度纯数字小数点且在 0~5 区间 → 1.0 raw_score item.get(score, 0) try: score_float float(raw_score) item[score_clean] score_float item[score_confidence] 1.0 if 0 score_float 5 else 0.2 except (ValueError, TypeError): item[score_clean] 0.0 item[score_confidence] 0.1 # 综合可信度加权平均电话 40%、地址 40%、评分 20% item[confidence_score] ( item.get(phone_confidence, 0) * 0.4 item.get(address_confidence, 0) * 0.4 item.get(score_confidence, 0) * 0.2 ) return item关键细节clean_addr re.sub(r\s, , clean_addr).strip()这一步不能省——大众点评地址字段常含多个连续空格或换行符不规整化会导致后续 NLP 分词失败item[score_clean]强制转float因为原始字段可能是字符串4.5或暂无评分下游数据库字段类型必须统一。这个 pipeline 不做“纠错”只做“标注”把决策权留给业务层比如 BI 报表只取confidence_score 0.7的数据而门店初筛可以放宽到 0.5。6. 最小化验证闭环3 行命令 1 个 CSV确认你的爬虫是否真的“可用”写完 spider别急着跑全量。我给自己定的铁律是每次修改中间件或 parser必须用这三步验证闭环否则不提交代码。它不保证 100% 生产就绪但能排除 90% 的低级错误。6.1 第一步用-s LOG_LEVELDEBUG抓单页看请求链是否完整scrapy crawl dianping -a start_urlhttps://www.dianping.com/shanghai/ch10/g110 \ -s LOG_LEVELDEBUG \ -s CLOSESPIDER_PAGECOUNT1 \ -o debug_single.json检查debug_single.json是否有数据再翻scrapy.log搜索Sending GET和Received 200确认 Referer、User-Agent、Cookie 全部按预期发出。6.2 第二步用scrapy check验证 spider 接口契约在spiders/dianping_spider.py顶部加 docstring声明输入输出DianpingShopSpider Input: start_url like https://www.dianping.com/city/ch10 Output: dict with keys: url, name, phone, address, score, review_count 然后运行scrapy check dianping它会自动调用parse_start_url和parse_shop_page检查 yield 的字段是否符合 docstring 声明——这是防“字段名写错”的后悔药。6.3 第三步用csvstat快速诊断数据质量需安装 csvkitscrapy crawl dianping -a cityshanghai -a pages5 -o temp.csv csvstat temp.csv --count --unique --nulls输出示例| Column | Count | Unique | Nulls | |--------|-------|--------|-------| | name | 1247 | 1242 | 0 | | phone | 1247 | 891 | 356 | | score | 1247 | 23 | 0 |→phone字段 356 个 null说明电话提取逻辑有缺陷score仅 23 个唯一值符合大众点评评分离散特性0.5 分一档属正常。这套验证流程我用了三年从没在上线后才发现response.css()全空。它不炫技但把“不确定”压缩到最小。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

列主元高斯消去法:浮点环境下线性方程组求解的稳定性基石

列主元高斯消去法:浮点环境下线性方程组求解的稳定性基石

简介:本资源是面向数值计算初学者与高校计算数学课程学习者的高斯消去法实践套件,聚焦线性方程组求解的核心算法实现与数值稳定性分析。压缩包共3个文件(2个C源码文件、1份实验报告文档),总大小230KB,轻量易…

2026/10/18 19:19:20 阅读更多 →
Python天气查询小程序:100行代码实现终端查天气

Python天气查询小程序:100行代码实现终端查天气

简介:这是一份由Python编写的天气查询小程序源码包,主要面向刚开始接触网络请求与数据解析的Python初学者,目的是演示如何通过公开天气接口获取实时气象信息。压缩包内共有两个文件,其中一个是以.py结尾的主程序脚本,负…

2026/10/18 19:19:20 阅读更多 →
DB2 V11.1 安装与性能调优实战:Linux 与 Windows 10 双平台指南

DB2 V11.1 安装与性能调优实战:Linux 与 Windows 10 双平台指南

简介:DB2 V11.1 是 IBM 面向大型企业推出的企业级关系型数据库管理系统,本资源为专为 Linux 环境打包的完整安装介质,适合需要在 Linux 服务器上搭建数据库服务的运维工程师、DBA 及数据库学习者使用。压缩包共 405 个文件,约 772…

2026/10/18 19:19:20 阅读更多 →

最新新闻

华为IGMP组播原理与实战:从精准调度到排障精要

华为IGMP组播原理与实战:从精准调度到排障精要

1. 为什么组播不是“群发”,而是一场精准的流量调度革命?很多人第一次听说IGMP,下意识就把它和微信群发、邮件群抄送划等号——“不就是让一台设备把数据同时发给多台设备吗?”这个理解方向错了,而且错得挺关键。我刚接…

2026/10/18 20:03:40 阅读更多 →
IPTV直播源管理系统:从m3u管理到全端稳定播放的工程实践

IPTV直播源管理系统:从m3u管理到全端稳定播放的工程实践

简介:这是一套基于Python开发的IPTV直播源管理系统可运行源码,面向具备基础Python开发与Web部署能力的技术爱好者、DIYP影音定制用户及中小型IPTV服务搭建者,解决直播源集中管理、动态配置与前端对接缺失的问题。资源包共29个文件&#xff0c…

2026/10/18 20:03:40 阅读更多 →
Maven三大生命周期与插件绑定机制:从mvn命令到构建流水线

Maven三大生命周期与插件绑定机制:从mvn命令到构建流水线

你在终端里敲下mvn clean install,回车,看着日志哗哗刷屏,最后等来一个 BUILD SUCCESS。但如果你被问一句:“这条命令到底让 Maven 做了多少事?”多半会愣一下。我刚开始用 Maven 那两年也是“会念咒不会解咒”&#x…

2026/10/18 20:03:40 阅读更多 →
STM32+TB6612电机驱动实战:PWM时序、死区防护与电流反馈闭环

STM32+TB6612电机驱动实战:PWM时序、死区防护与电流反馈闭环

简介:本资源是一份面向嵌入式初学者与STM32实践者的电机控制实战代码包,聚焦于使用STM32F103C8T6微控制器驱动TB6612FNG双H桥电机模块,解决直流电机PWM调速、正反转及小车运动状态封装控制等核心问题。压缩包共16个文件,含5个头文…

2026/10/18 20:03:40 阅读更多 →
电力系统通信设计内容深度规定:从可研到施工图的深度要求与避坑指南

电力系统通信设计内容深度规定:从可研到施工图的深度要求与避坑指南

简介:这份《电力系统通信设计内容深度规定》文档面向电力系统通信设计人员、电网调度与自动化工程师及相关专业师生,用于规范通信规划与系统通信设计各阶段的内容深度要求。文档共1个doc文件,压缩包约25KB,内容涵盖总则、电力系统…

2026/10/18 20:03:40 阅读更多 →
2026论文降AI全攻略:从检测原理到三轮返修法

2026论文降AI全攻略:从检测原理到三轮返修法

2026年,论文提交系统里的AIGC检测普遍又升了一级。最近找我咨询的同学,十个有八个开场白是同一句话:“我的论文AI率60%多,怎么降AI?”光这句话我就听了几百遍。今天这篇不绕弯子,把这套完整方案从头到尾写清…

2026/10/18 20:02:39 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →