You need to enable JavaScript to run this app. 使用Scrapy Files Pipeline按年份范围下载IRS税表PDF的实现与故障排查
优惠活动
大模型
产品
解决方案
定价
更多

使用Scrapy Files Pipeline按年份范围下载IRS税表PDF的实现与故障排查

核心问题根因定位

一、导致“仅访问起始页就被终止”的常见代码错误

  • 未正确禁用robots.txt遵循规则
    Scrapy默认开启ROBOTSTXT_OBEY = True,IRS站点的robots.txt对列表页爬取的限制较严格,若未在settings.py中显式写入ROBOTSTXT_OBEY = False(哪怕命令行临时修改也容易失效),爬虫会在抓取首页解析链接时,被robots规则判定为无权访问后续列表、详情页,直接终止所有请求队列,完全匹配你描述的运行现象。
  • 解析逻辑空转
    部分代码写在解析起始页的方法中未正确提取列表条目、翻页链接,返回空的Request集合,表面日志看起来是被robots拦截终止,实际是没有可继续执行的任务队列。
  • Files Pipeline配置失效
    未在ITEM_PIPELINES中正确启用文件下载管道,哪怕抓到了PDF链接,也不会触发实际下载流程,日志表现为爬完初始页就无后续动作。

二、导致无法实现需求的逻辑缺陷

  • 未重写FilesPipeline的路径生成规则:Scrapy默认会将下载的文件按MD5哈希值直接存在FILES_STORE根目录下,完全无法满足“按表单名建子目录、自定义PDF文件名”的要求。
  • 未做年份范围过滤:解析时无针对性判断,会把所有年份的税表都爬下来,不符合指定范围下载的需求。
可落地的完整实现方案

1. settings.py 必改配置

直接在配置文件中写入以下参数,避免依赖默认值导致配置失效:

# 禁用robots遵循规则
ROBOTSTXT_OBEY = False
# 配置真实浏览器UA,避免被站点WAF拦截
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
# 配置下载延迟,降低服务器压力
DOWNLOAD_DELAY = 1
# 配置文件存储根目录
FILES_STORE = "./irs_tax_forms"
# 替换为自定义管道类,见下文代码
ITEM_PIPELINES = {
    "pdf.CustomIRSFilesPipeline": 1,
}
# 对应Item的字段映射,匹配FilesPipeline的参数要求
FILES_URLS_FIELD = "file_urls"
FILES_RESULT_FIELD = "files"

2. 自定义FilesPipeline 实现目录与文件名规则

注意:不要直接调用Scrapy自带的默认FilesPipeline,默认路径规则是将所有下载文件按内容哈希值存在根目录,完全无法匹配你要求的目录结构与文件命名格式。
在pdf.py中重写FilesPipeline的路径生成方法,完全匹配存储要求:

from scrapy.pipelines.files import FilesPipeline
from scrapy import Item, Field

# 定义爬取用的Item结构
class TaxFormItem(Item):
    form_name = Field()  # 存储表单名称,比如Form W-2
    form_year = Field()  # 存储对应年份,比如2020
    file_urls = Field()  # 存储PDF下载链接

class CustomIRSFilesPipeline(FilesPipeline):
    def file_path(self, request, response=None, info=None, *, item=None):
        # 过滤表单名中的Windows/macOS非法文件名字符
        safe_form_name = item["form_name"].replace("/", "_").replace("\\", "_").strip()
        # 生成目标路径:表单名目录/表单名 - 年份.pdf
        return f"{safe_form_name}/{item['form_name']} - {item['form_year']}.pdf"

3. Spider 核心爬取逻辑实现

在pdf.py中编写Spider类,实现列表解析、年份过滤、翻页抓取逻辑:

import scrapy

class IRSTaxFormSpider(scrapy.Spider):
    name = "irs_tax_form"
    start_urls = ["https://apps.irs.gov/app/picklist/list/priorFormPublication.html"]
    # 配置需要爬取的年份范围,可按需修改
    TARGET_YEARS = set(range(2018, 2021))

    def parse(self, response):
        # 遍历当前页所有税表单条目
        for row in response.xpath("//table[@class='picklist-dataTable']/tr")[1:]:
            # 提取条目对应的表单名
            form_name = row.xpath("./td[1]/a/text()").get()
            # 提取条目对应的年份
            form_year = int(row.xpath("./td[2]/span/text()").get().strip())
            # 提取PDF下载链接
            pdf_url = row.xpath("./td[1]/a/@href").get()
            
            # 只保留目标年份范围内的条目
            if form_year in self.TARGET_YEARS:
                yield TaxFormItem(
                    form_name=form_name,
                    form_year=form_year,
                    file_urls=[response.urljoin(pdf_url)]
                )
        
        # 提取翻页链接,递归爬取后续列表页
        next_page = response.xpath("//a[contains(text(), 'Next')]/@href").get()
        if next_page:
            yield response.follow(next_page, callback=self.parse)

关键注意事项

  • 解析XPath选择器可根据实际页面结构微调,避免出现条目错位(比如把年份和PDF链接对应错)
  • 运行时直接执行scrapy runspider pdf.py即可,无需额外启动配置
  • 可自行增加URL去重逻辑,避免同一个PDF被重复提交下载

内容的提问来源于stack exchange,提问作者alivingpixel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.05 13:27:02