我之前asked a question关于重复使用我编写的parse
方法,以便我的蜘蛛表现不同,具体取决于它是否在start_urls
参数中传递。如果是,它应仅抓取这些给定的URL(不要关注),但如果不抓取,则应抓取整个站点(按照链接)。
我得到的答案非常有用且运作良好,并产生了CrawlSpider
这样的定义:
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
from scrapy.selector import Selector
from foo.items import FooItem
from scrapy.contrib.loader import ItemLoader
import json
import datetime
import re
class FooSpider(CrawlSpider):
name = "foo"
allowed_domains = ["example.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://example.com/"]
self.rules = [
Rule(LinkExtractor(allow=[], deny=['/blog']), follow=True, callback='parse_response'),
]
super(FooSpider, self).__init__(*args, **kwargs)
def parse_response(self, response):
sel = Selector(response)
if not(sel.css('div.product-view')):
return None
l = ItemLoader(item=FooItem(), response=response)
product = l.load_item()
return product
但是,我现在刚刚发现example.com有一个我可以使用的站点地图,而不是必须抓取整个站点。所以我像这样更新我的蜘蛛:
class FooSpider(SitemapSpider):
name = "foo"
sitemap_urls = ['http://example.com/sitemap.xml']
sitemap_rules = [('/', 'parse_response')]
但此时我发现SitemapSpider
的行为与CrawlSpider
不同,并且不会以与我之前定义相同的方式接受start_urls
。那么有没有办法保留名为"foo"
的单个蜘蛛的先前行为,该蜘蛛根据start_urls
参数委托行为?
我不太了解Python,并且开始认为我可以有一个FooSpider
基类,它根据参数动态返回一个子类,但现在我认为它可能无效。我开始思考的草图代码(不工作):
class FooSpider(Spider):
name = "foo"
def __init__(self, start_urls=None, *args, **kwargs):
if start_urls:
self.start_urls = json.loads(start_urls)
FooCrawlSpider.__init__(self, *args, **kwargs)
else:
FooSitemapSpider.__init__(self, *args, **kwargs)
def parse_response(self, response):
sel = Selector(response)
if not(sel.css('div.product-view')):
return None
l = ItemLoader(item=FooItem(), response=response)
product = l.load_item()
return product
class FooCrawlSpider(CrawlSpider, FooSpider):
allowed_domains = ["example.com"]
rules = []
parse = self.parse_response
class FooSitemapSpider(SitemapSpider, FooSpider):
sitemap_urls = ['http://example.com/sitemap.xml']
sitemap_rules = [('/', 'parse_response')]
我缺乏Python知识在这里引起了我的注意。任何想法,将不胜感激!最糟糕的情况我总是可以创建具有不同name
s的单独蜘蛛。