Я хочу создать отдельный выходной файл для каждого URL-адреса, который я установил в start_urls паука, или каким-то образом хочу разделить выходные файлы на начальный 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
Я точно не знаю, как это сделать. Я думаю добиться этого, внедрив что-то вроде следующего в методе 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
Где я пытаюсь найти URL-адрес реферера каждого очищенного элемента в списке start_urls. Если URL-адрес реферера найден в start_urls, то имя файла будет создано с использованием этого URL-адреса реферера. Но проблема в том, как получить доступ к объекту ответа внутри метода 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
в пауке, чтобы установить start_url для каждого элемента.
def make_requests_from_url(self, url):
request = Request(url, dont_filter=True)
request.meta['start_url'] = url
return request