如何按域名分别存储Scrapy全网爬取的结果?
实现按域名拆分Scrapy爬取结果到S3独立文件
方法1:利用FEEDS动态路径+Item域名字段
这是最简洁的实现方式,依赖Scrapy原生的动态路径渲染能力:
- 在爬虫中给Item添加
domain字段,提取当前响应的域名:
from scrapy.item import Item, Field from urllib.parse import urlparse class MyItem(Item): title = Field() content = Field() domain = Field() # 新增存储域名的字段 class MultiDomainSpider(scrapy.Spider): name = 'multi_domain_crawler' start_urls = ['https://example.com', 'https://test.org'] def parse(self, response): item = MyItem() item['title'] = response.xpath('//title/text()').get() item['content'] = response.xpath('//body//text()').getall() # 从响应URL中提取域名 parsed_url = urlparse(response.url) item['domain'] = parsed_url.netloc yield item
- 在
settings.py中配置FEEDS,用%(domain)s作为路径变量,Scrapy会自动根据Item的domain字段拆分文件:
FEEDS = { 's3://your-bucket-name/%(domain)s/items.json': { 'format': 'json', 'overwrite': False, 'encoding': 'utf-8', 'fields': None # 保留所有字段(包括domain) } }
配置完成后,S3中会生成example.com/items.json、test.org/items.json这类独立文件,每个域名的爬取结果自动归类。
方法2:自定义Feed Exporter(复杂场景适配)
如果需要更灵活的拆分逻辑(比如按域名+日期拆分),可以自定义Feed Exporter:
- 在项目目录下创建
exporters.py:
from scrapy.exporters import JsonItemExporter from scrapy.extensions.feedexport import FeedExporter from urllib.parse import urlparse class DomainSplitExporter(FeedExporter): def __init__(self, uri, **kwargs): super().__init__(uri, **kwargs) self.domain_exporters = {} # 存储每个域名对应的导出器 def open(self): # 无需提前打开全局文件,按需创建域名专属文件 pass def export_item(self, item): domain = item.get('domain') if not domain: return # 构建对应域名的S3路径 bucket_prefix = self.uri.split('s3://your-bucket-name/')[0] target_path = f"{bucket_prefix}s3://your-bucket-name/{domain}/items.json" if domain not in self.domain_exporters: # 为新域名创建导出器 exporter = JsonItemExporter( self.filesystem.open(target_path, mode='ab'), **self.exporter_kwargs ) exporter.start_exporting() self.domain_exporters[domain] = exporter self.domain_exporters[domain].export_item(item) def close(self): # 关闭所有域名的导出器 for exporter in self.domain_exporters.values(): exporter.finish_exporting() exporter.file.close()
- 在
settings.py中指定使用自定义导出器:
FEEDS = { 's3://your-bucket-name/temp.json': { 'format': 'json', 'exporter': 'your_project_name.exporters.DomainSplitExporter', 'overwrite': False } }
关键注意事项
- 必须确保爬虫正确提取并传递
domain字段,这是拆分逻辑的核心依据。 - 提前配置AWS权限:在
settings.py中设置AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY,确保Scrapy有目标S3桶的写入权限。 - 使用动态路径时,Scrapy会自动处理文件的创建与追加,无需手动管理文件句柄。
内容的提问来源于stack exchange,提问作者NightOwl
相关产品推荐
相关产品推荐

