Я бы хотел разделить разбор на разных пауков.
В настоящее время у меня есть:
class CategoriesSpider(scrapy.Spider):
name = 'categories'
allowed_domains = ['example.org']
start_urls = ['https://example.org/categories']
def parse(self, response):
for link in response.xpath("//div[@class='something']/@href"):
yield scrapy.Request(response.urljoin(link.root), callback=self.parse_actual_item_i_want)
def parse_actual_item_i_want(self, response):
yield self.find_the_item(response)
А теперь разбить его на:
class OneThingSpider(scrapy.Spider):
name = 'one_thing'
allowed_domains = ['example.org']
start_urls = ['https://example.org/']
def __init__(self, url: str):
if url == None or url == "":
raise ValueError("Invalid url given")
# Exact URL and it's format is not known
self.start_urls = [url]
def parse(self, response):
yield self.find_the_item(response)
Итак что если обновляется только одна вещь, я могу использовать только OneThingSpider
Так где и как я называю OneThingSpider
внутри CategoriesSpider
или конвейером?
Я пробовал вот это:
Внутри CategoriesSpider
попытки # 1:
def parse(self, response):
for link in response.xpath("//div[@class='something']/@href"):
yield self.crawler.crawl("one_thing", response.urljoin(link.root))
В попытке конвейера # 1:
В CategoriesSpider
:
def parse(self, response):
for link in response.xpath("//div[@class='something']/@href"):
yield CategoryUrl({"url": response.urljoin(link.root)})
В конвейере:
class MyPipeline(object):
def process_item(self, item, spider):
if isinstance(item, CategoryUrl):
spider.crawler.crawl("one_thing", item["url"])
return
# this part works
if isinstance(item, ItemIWant):
with open(...)
В конвейере попытка # 2:
То же изменение в CategoriesSpider
, что и при попытке # 1. Здесь мы просто пытаемся получить sh URL-адреса OneThingSpider
после закрытия CategoriesSpider
.
В конвейере:
class MyPipeline(object):
urls = []
def process_item(self, item, spider):
if isinstance(item, CategoryUrl):
self.urls.append(item["url"])
spider.crawler.crawl("one_thing", item["url"])
return
# this part works
if isinstance(item, ItemIWant):
with open(...)
def close_spider(self, spider):
if spider.name == "categories":
for url in self.urls:
spider.crawler.crawl("one_thing", url)
Ошибка, которую я получаю, заключается в том, что гусеничный уже ползет . Итак, как правильно разделить паука на более мелких пауков?
Цель состоит в том, что я могу бегать:
scrapy crawl categories
, а также
scrapy crawl one_thing -a url="https://example.org/something/xyz.html"