我想为我在spider的start_urls中设置的每个URL创建单独的输出文件,或者以某种方式想要分割输出文件,以明智的方式启动url。
以下是我的蜘蛛的start_urls
start_urls = ['http://www.dmoz.org/Arts/', 'http://www.dmoz.org/Business/', 'http://www.dmoz.org/Computers/']
我想创建单独的输出文件,如
Arts.xml
Business.xml
Computers.xml
我不知道该怎么做。我正在考虑通过在item管道类的spider_opened方法中实现以下操作来实现这一点,
import re
from scrapy import signals
from scrapy.contrib.exporter import XmlItemExporter
class CleanDataPipeline(object):
def __init__(self):
self.cnt = 0
self.filename = ''
@classmethod
def from_crawler(cls, crawler):
pipeline = cls()
crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
return pipeline
def spider_opened(self, spider):
referer_url = response.request.headers.get('referer', None)
if referer_url in spider.start_urls:
catname = re.search(r'/(.*)$', referer_url, re.I)
self.filename = catname.group(1)
file = open('output/' + str(self.cnt) + '_' + self.filename + '.xml', 'w+b')
self.exporter = XmlItemExporter(file)
self.exporter.start_exporting()
def spider_closed(self, spider):
self.exporter.finish_exporting()
#file.close()
def process_item(self, item, spider):
self.cnt = self.cnt + 1
self.spider_closed(spider)
self.spider_opened(spider)
self.exporter.export_item(item)
return item
我在哪里尝试在start_urls列表中找到每个已抓取项目的引用网址。如果在start_urls中找到引用网址,则将使用该引用网址创建文件名。但是问题是如何在spider_opened()方法内访问响应对象。如果可以在那里访问它,则可以基于该文件创建文件。
有帮助找到执行此操作的方法吗?提前致谢!
[编辑]
通过更改管道代码如下解决了我的问题。
import re
from scrapy import signals
from scrapy.contrib.exporter import XmlItemExporter
class CleanDataPipeline(object):
def __init__(self):
self.filename = ''
self.exporters = {}
@classmethod
def from_crawler(cls, crawler):
pipeline = cls()
crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
return pipeline
def spider_opened(self, spider, fileName = 'default.xml'):
self.filename = fileName
file = open('output/' + self.filename, 'w+b')
exporter = XmlItemExporter(file)
exporter.start_exporting()
self.exporters[fileName] = exporter
def spider_closed(self, spider):
for exporter in self.exporters.itervalues():
exporter.finish_exporting()
def process_item(self, item, spider):
fname = 'default'
catname = re.search(r'http://www.dmoz.org/(.*?)/', str(item['start_url']), re.I)
if catname:
fname = catname.group(1)
self.curFileName = fname + '.xml'
if self.filename == 'default.xml':
if os.path.isfile('output/' + self.filename):
os.rename('output/' + self.filename, 'output/' + self.curFileName)
exporter = self.exporters['default.xml']
del self.exporters['default.xml']
self.exporters[self.curFileName] = exporter
self.filename = self.curFileName
if self.filename != self.curFileName and not self.exporters.get(self.curFileName):
self.spider_opened(spider, self.curFileName)
self.exporters[self.curFileName].export_item(item)
return item
同样make_requests_from_url
在Spider中实现,可以为每个项目设置start_url。
def make_requests_from_url(self, url):
request = Request(url, dont_filter=True)
request.meta['start_url'] = url
return request
我将采用更明确的方法(未经测试):
在以下位置配置可能类别的列表settings.py
:
CATEGORIES = ['Arts', 'Business', 'Computers']
start_urls
根据设置定义您的
start_urls = ['http://www.dmoz.org/%s' % category for category in settings.CATEGORIES]
添加category
Field
到Item
类
在Spider的parse方法中,category
根据current设置字段response.url
,例如:
def parse(self, response):
...
item['category'] = next(category for category in settings.CATEGORIES if category in response.url)
...
在管道中,打开所有类别的出口商,然后根据以下条件选择要使用的出口商item['category']
:
def spider_opened(self, spider):
...
self.exporters = {}
for category in settings.CATEGORIES:
file = open('output/%s.xml' % category, 'w+b')
exporter = XmlItemExporter(file)
exporter.start_exporting()
self.exporters[category] = exporter
def spider_closed(self, spider):
for exporter in self.exporters.itervalues():
exporter.finish_exporting()
def process_item(self, item, spider):
self.exporters[item['category']].export_item(item)
return item
您可能需要对其进行一些微调才能使其正常工作,但我希望您有主意-将类别存储在item
正在处理的内部。根据项目类别值选择要导出到的文件。
希望能有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句