gpt4 book ai didi

python - 如何在继承的 CrawlSpider 中重用基于 scrapy Spider 的蜘蛛的解析方法?

转载 作者:太空狗 更新时间:2023-10-30 03:00:46 26 4
gpt4 key购买 nike

我目前有一个基于 Spider 的蜘蛛,我编写它用于抓取 start_urls 的输入 JSON 数组。 :

from scrapy.spider import Spider
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor

from foo.items import AtlanticFirearmsItem
from scrapy.contrib.loader import ItemLoader

import json
import datetime
import re

class AtlanticFirearmsSpider(Spider):
name = "atlantic_firearms"
allowed_domains = ["atlanticfirearms.com"]

def __init__(self, start_urls='[]', *args, **kwargs):
super(AtlanticFirearmsSpider, self).__init__(*args, **kwargs)
self.start_urls = json.loads(start_urls)

def parse(self, response):
l = ItemLoader(item=AtlanticFirearmsItem(), response=response)
product = l.load_item()
return product

我可以像这样从命令行调用它,它做得很好:

scrapy crawl atlantic_firearms -a start_urls='["http://www.atlanticfirearms.com/component/virtuemart/shipping-rifles/ak-47-receiver-aam-47-detail.html", "http://www.atlanticfirearms.com/component/virtuemart/shipping-accessories/nitride-ak47-7-62x39mm-barrel-detail.html"]'

但是,我正在尝试添加一个基于 CrawlSpider 的蜘蛛来抓取从它继承的整个站点并重新使用 parse方法逻辑。我的第一次尝试是这样的:

class AtlanticFirearmsCrawlSpider(CrawlSpider, AtlanticFirearmsSpider):
name = "atlantic_firearms_crawler"
start_urls = [
"http://www.atlanticfirearms.com"
]
rules = (
# I know, I need to update these to LxmlLinkExtractor
Rule(SgmlLinkExtractor(allow=['detail.html']), callback='parse'),
Rule(SgmlLinkExtractor(allow=[], deny=['/bro', '/news', '/howtobuy', '/component/search', 'askquestion'])),
)

运行这个蜘蛛

scrapy crawl atlantic_firearms_crawler

抓取站点但从不解析任何项目。我认为这是因为 CrawlSpider apparently has its own definition of parse , 所以不知何故我把事情搞砸了。

当我改变 callback='parse'callback='parse_item'并重命名 parse AtlanticFirearmsSpider 中的方法至 parse_item , 它工作得很好,成功地抓取了整个站点并解析了项目。但是如果我尝试调用我原来的 atlantic_firearms蜘蛛再次出现,它出错了 NotImplementedError ,显然是因为基于蜘蛛的蜘蛛真的希望将解析方法定义为 parse .

对我来说,在这些蜘蛛之间重用我的逻辑的最佳方式是什么,这样我就可以同时提供 start_urls 的 JSON 数组。以及全站抓取?

最佳答案

您可以在这里避免多重继承

将两个蜘蛛合并为一个。如果 start_urls 将从命令行传递 - 它会表现得像一个 CrawlSpider,否则就像一个普通的蜘蛛:

from scrapy import Item
from scrapy.contrib.spiders import CrawlSpider, Rule

from foo.items import AtlanticFirearmsItem
from scrapy.contrib.loader import ItemLoader
from scrapy.contrib.linkextractors import LinkExtractor

import json


class AtlanticFirearmsSpider(CrawlSpider):
name = "atlantic_firearms"
allowed_domains = ["atlanticfirearms.com"]

def __init__(self, start_urls=None, *args, **kwargs):
if start_urls:
self.start_urls = json.loads(start_urls)
self.rules = []
self.parse = self.parse_response
else:
self.start_urls = ["http://www.atlanticfirearms.com/"]
self.rules = [
Rule(LinkExtractor(allow=['detail.html']), callback='parse_response'),
Rule(LinkExtractor(allow=[], deny=['/bro', '/news', '/howtobuy', '/component/search', 'askquestion']))
]

super(AtlanticFirearmsSpider, self).__init__(*args, **kwargs)

def parse_response(self, response):
l = ItemLoader(item=AtlanticFirearmsItem(), response=response)
product = l.load_item()
return product

或者,也可以将 parse() 方法中的逻辑提取到一个库函数中,然后从两个不相关的蜘蛛、单独的蜘蛛中调用。

关于python - 如何在继承的 CrawlSpider 中重用基于 scrapy Spider 的蜘蛛的解析方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28080496/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com