CrawlerProcess中只有一个Spider使用定义的ItemPipeline。为什么?

时间:2018-01-29 15:41:43

标签: mongodb scrapy

我在CrawlerProcess中运行两个蜘蛛:

    if __name__ == '__main__':
process = CrawlerProcess({'USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
                          'ITEM_PIPELINES': {'CampusScraper.pipelines.Item_to_MongoDB': 100}})
process.crawl(CampusCoursesCrawler)
process.crawl(CampusResourceCrawler)
process.start()

它们大多是独立的,但我想通过ItemPipeline将输出保存到MongoDB

class Item_to_MongoDB(object):
path = 'localhost:27017'
client = MongoClient(path)
document = None

def select_document(self, item, spider):
    if item['Spider'] == 'resources_crawler': return ('Resources', 'Key')
    if item['Spider'] == 'courses_crawler': return ('Courses', 'ID')
    if item['Spider'] == 'exams': return ('Exams', 'ID')

def process_item(self, item, spider):
    document, key = self.select_document(item, spider)
    self.client.Campus[document].update({key : item[key]}, {'$set': item}, upsert=True)

def close_spider(self):
    self.client.close()

这两个项目在被item_loader处理之前似乎很好地填充:

   def populate_db(self, response, data):
    l = ItemLoader(item=CourseItem(), response=response)
    l.add_value('ID', data['id'])
    l.add_value('Course_Number', data['course_number'])
    l.add_value('Name', data['name'])
    l.add_value('Visibility', data['visibility'])
    l.add_value('Exams', data['exams'])
    l.add_value('Classes', data['classes'])
    l.add_value('Product', data['product'])
    l.add_value('Owner', data['owner'])
    l.add_value('Active', data['active'])
    l.add_value('Discoverable', data['discoverable'])
    l.add_value('Edit_URL', response.url)
    l.add_value('Description', data['description'])
    l.add_value('Course_Video', data['course_video'])
    l.add_value('Modules', data.get('modules'))
    l.add_value('Spider', self.name)
    return l.load_item()

    def parse_resource(self, response):
    overview_tabel = response.meta['overview_table']
    l = ItemLoader(item=ResourceItem(), response=response)
    l.add_value('ID', overview_tabel['key_id'])
    l.add_value('Key', overview_tabel['key_id'])
    l.add_value('Type', overview_tabel['type'])
    l.add_value('Name', overview_tabel['name'])
    l.add_value('Modification_Date', overview_tabel['modification_date'])
    l.add_value('Language', overview_tabel['language'])
    l.add_value('Owner', overview_tabel['owner'])
    l.add_value('Active', overview_tabel['active'])
    l.add_value('Discoverable', overview_tabel['discoverable'])
    l.add_value('Edit_URL', response.url)
    l.add_value('Display_URL', overview_tabel['key_id'])
    l.add_xpath('Description', '//*[@id="desc_long"]/text()')
    l.add_xpath('Filename', '//*[@id="displayfilename"]/@value')
    l.add_xpath('Attached_Courses', '//*[@id="attached_courses"]/option/text()')
    l.add_xpath('Roles', '//*[@id="attached_skills"]/option/text()')
    l.add_xpath('Products', '//*[@id="attached_products"]/option/text()')
    l.add_xpath('Permissions', '//*[@id="ref_form"]/div[1]/section[2]/div[3]/div[2]/ul')
    l.add_value('Spider', self.name)
    return l.load_item()

一切都适用于ResourceCrawler,但CoursesCrawler不会启动管道。有什么想法吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

问题在于蜘蛛本身(正如有些人猜测的那样)。对于任何有类似神秘问题的人:我调用了具有ItemLoader而不是返回它的函数。这使得ItemPipeline无法被调用。