5月31日 01:07

Scrapy 调试和日志怎么做?Shell、parse 命令和 stats 如何配合排查?

先说结论

Scrapy 调试不要只靠 print,更高效的做法是把 shell、parse 命令、日志级别、stats 指标和少量断点组合起来。选择器写不准,用 scrapy shell;单个 URL 的回调链路不对,用 scrapy parse;线上任务异常,用日志和 stats 定位是请求失败、解析为空,还是 Pipeline 写入出错。日志要能回答“发生了什么、发生在哪个 URL、影响多少数据”,而不是把控制台刷满。

常用命令如下:

bash
scrapy shell "https://example.com/list" scrapy parse "https://example.com/list" --spider=demo -c parse scrapy crawl demo -s LOG_LEVEL=DEBUG scrapy crawl demo -s LOG_FILE=logs/demo.log

DEBUG 适合本地排查,线上长期跑一般用 INFOWARNING。如果日志太吵,真正的问题会被淹没;如果日志太少,任务失败时又只能重跑碰运气。

用 shell 调选择器

scrapy shell 会拿到和爬虫接近的 response 对象,可以直接测试 CSS、XPath 和正则。比如先确认标题是否存在,再确认列表长度,而不是写完 spider 后才发现字段全是空。

python
response.css("h1::text").get() response.css(".item").getall()[:2] response.xpath("//a/@href").getall()

边界是 shell 只代表当前 URL 和当前响应。很多站点会按地区、登录态、User-Agent 或反爬策略返回不同内容,本地 shell 成功不等于线上一定成功。遇到这种情况,要把请求头、cookie、代理和中间件一起纳入排查。

用 parse 命令检查回调

scrapy parse 能执行指定回调,并展示产生了哪些 item 和 request。它比 shell 更接近 spider 的真实逻辑,适合排查“选择器没问题,但爬虫就是没产出”的情况。常见原因包括回调方法没挂上、规则没匹配、分页链接被过滤、allowed_domains 写错。

如果请求被 dupefilter 去重,可以临时给关键请求加 dont_filter=True 验证。这个设置不要滥用,线上乱加会让重复页面暴涨。

日志应该记录什么

Scrapy 使用 Python logging,可以在 spider、middleware、pipeline 中按模块打日志。建议记录关键 URL、业务 ID、状态码、解析数量和异常原因,不要把完整 HTML 或大 item 直接打进日志。

python
import logging logger = logging.getLogger(__name__) logger.info("parsed list", extra={"url": response.url, "count": len(items)}) logger.warning("empty detail", extra={"url": response.url})

settings.py 里可以控制输出:

python
LOG_LEVEL = "INFO" LOG_FILE = "logs/spider.log" LOG_FORMAT = "%(asctime)s [%(name)s] %(levelname)s: %(message)s"

stats 比单条日志更适合看趋势

日志告诉你某次发生了什么,stats 告诉你整体发生了多少次。比如 item_scraped_countdownloader/exception_countretry/count、各状态码数量,都能快速判断问题范围。你也可以在代码里自定义计数,例如空列表页、缺字段详情页、入库失败次数。

python
self.crawler.stats.inc_value("custom/empty_detail")

追问

shell 能调通,爬虫跑起来却没有数据,怎么排查?

先用 scrapy parse 跑同一个 URL,确认 spider 的回调是否真的产出 item。再看分页或详情页 request 有没有被 allowed_domains、去重器或中间件拦掉。shell 只验证选择器,不验证调度链路,这是它的边界。实际排查时要把 response、callback 和后续 request 放在一起看。

日志级别应该怎么选?

本地开发用 DEBUG,因为你需要看到请求、重试和解析细节。线上长期任务更适合 INFOWARNING,否则日志量会迅速膨胀,磁盘和检索成本都上来。取舍是日志越详细,定位越快,但噪声也越大。关键是把业务异常打清楚,而不是依赖框架默认日志。

什么时候用 pdb 或 IDE 断点?

当问题发生在复杂条件分支、字段清洗或 Pipeline 写入逻辑里,断点比反复打日志更快。边界是异步框架里随意断住会影响请求调度,本地可以这么做,线上不要这么排查。更稳的方式是用固定样本、关闭高并发,只跑一两个 URL。断点解决“为什么走到这里”,日志和 stats 解决“这种情况发生了多少”。

stats 能发现哪些日志不容易发现的问题?

stats 很适合发现比例异常,比如 200 状态很多但 item 很少,说明解析可能失效。也能发现重试暴涨、某类异常集中出现、入库失败次数上升。单条日志容易让人盯着个例,stats 能先判断是不是系统性问题。踩坑点是自定义指标命名要稳定,否则不同版本之间没法对比。

日志写文件有什么注意事项?

写文件前先确认目录存在,并考虑日志轮转,否则长跑任务可能把磁盘写满。Scrapy 的 LOG_FILE 简单好用,但多爬虫、多进程时要避免都写同一个文件。敏感字段也不要进日志,比如 cookie、token、手机号和完整地址。日志是排障材料,不应该变成新的安全风险。

标签:Scrapy