PyCharm环境下使用Scrapy爬取站点PDF无下载结果及需求实现咨询
问题根因拆解
- 配置生效规则认知偏差:当前代码中定义的
ITEM_PIPELINES、FILES_STORE属于Scrapy全局项目配置,直接写在Spider脚本内不会被框架加载,文件下载管道完全未启用,是导致无任何PDF落盘的核心原因 - 提取逻辑无容错与筛选:当前XPath仅提取首个匹配节点的链接,既未增加
spec_sheet关键词的筛选判断,也未处理页面无匹配元素时file_url为None的边界情况,空值传入管道会触发静默异常,导致下载任务无法正常入队 - 默认管道命名逻辑不匹配需求:原生
FilesPipeline会基于文件内容哈希生成无意义的随机文件名,不会保留网站侧的原始PDF文件名,不符合存储要求
分步修正方案
1. 全局配置迁移
将Spider脚本内的全局配置移动到项目根目录的settings.py文件中,补充必要的下载参数:
# 写入settings.py的配置内容 ITEM_PIPELINES = {'scrapy.pipelines.files.FilesPipeline': 1} FILES_STORE = '/Users/lukewoods/Desktop/AppDev/LightingPDFs/Martin' MEDIA_ALLOW_REDIRECTS = True
注意:直接删除Spider脚本内重复的配置定义,避免逻辑混淆
2. 自定义管道实现原始文件名留存
在项目目录下新建pipelines.py文件,继承原生FilesPipeline重写文件路径生成逻辑,从下载链接中提取真实的PDF文件名:
# 项目pipelines.py内的自定义管道代码 from scrapy.pipelines.files import FilesPipeline from urllib.parse import urlparse, unquote class OriginalNameFilesPipeline(FilesPipeline): def file_path(self, request, response=None, info=None, *, item=None): # 解析链接路径,解码URL编码的特殊字符 link_path = urlparse(request.url).path raw_file_name = unquote(link_path.split('/')[-1]) # 统一补全PDF后缀,避免无效文件存储 if not raw_file_name.endswith('.pdf'): raw_file_name = f"{raw_file_name}.pdf" return raw_file_name
调整settings.py中的管道配置,替换为自定义管道:
ITEM_PIPELINES = { '当前项目名称.pipelines.OriginalNameFilesPipeline': 1 }
3. 调整Spider内的链接筛选规则
修改parse_item方法,增加链接筛选与容错逻辑,仅将包含spec_sheet关键词的PDF链接传入下载队列:
def parse_item(self, response): # 提取页面所有下载区链接 download_links = response.xpath("//tr[@class='download-item-row']/a/@href").getall() for link in download_links: absolute_link = response.urljoin(link) # 严格筛选目标spec_sheet类PDF文件 if 'spec_sheet' in absolute_link and absolute_link.lower().endswith('.pdf'): item = ZipfilesItem() item['file_urls'] = [absolute_link] yield item
内容的提问来源于stack exchange,提问作者Luke Woods
相关产品推荐
相关产品推荐

