Как использовать мета в правиле терапии

def parse(self,response):
    my_item={'test':123,'test2':321}
    google_url = 'https://www.google.com/search?q=coffee+cans'
    yield Request(url=google_url,callback=self.google,meta={'my_item':my_item})

def google(self,response):
    my_item = response.meta['my_item']
    rules = (
        Rule(LinkExtractor(restrict_xpaths='//div[@class="r"]/a',allow='/dp',allow_domains='chewy.com'),
            callback="chewy"),
        Rule(LinkExtractor(restrict_xpaths='//div[@class="r"]/a',allow='/p/',allow_domains='homedepot.com'),
            process_request=request.meta['my_item']=my_item,callback='homedepot')
        )
def homedepot(self,response):
    #my_item = response.meta['my_item']

сообщение об ошибке:

Traceback (most recent call last):
  File "/home/timmy/.local/bin/scrapy", line 11, in <module>
    sys.exit(execute())
  File "/home/timmy/.local/lib/python3.6/site-packages/scrapy/cmdline.py", line 149, in execute
    cmd.crawler_process = CrawlerProcess(settings)
  File "/home/timmy/.local/lib/python3.6/site-packages/scrapy/crawler.py", line 251, in __init__
    super(CrawlerProcess, self).__init__(settings)
  File "/home/timmy/.local/lib/python3.6/site-packages/scrapy/crawler.py", line 137, in __init__
    self.spider_loader = _get_spider_loader(settings)
  File "/home/timmy/.local/lib/python3.6/site-packages/scrapy/crawler.py", line 338, in _get_spider_loader
    return loader_cls.from_settings(settings.frozencopy())
  File "/home/timmy/.local/lib/python3.6/site-packages/scrapy/spiderloader.py", line 61, in from_settings
    return cls(settings)
  File "/home/timmy/.local/lib/python3.6/site-packages/scrapy/spiderloader.py", line 25, in __init__
    self._load_all_spiders()
  File "/home/timmy/.local/lib/python3.6/site-packages/scrapy/spiderloader.py", line 47, in _load_all_spiders
    for module in walk_modules(name):
  File "/home/timmy/.local/lib/python3.6/site-packages/scrapy/utils/misc.py", line 71, in walk_modules
    submod = import_module(fullpath)
  File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 781, in get_code
  File "<frozen importlib._bootstrap_external>", line 741, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/timmy/scrapy_tut/myproject/spiders/amazon.py", line 62
    process_request=request.meta['my_item']=my_item,callback='homedepot')
                                           ^
SyntaxError: invalid syntax

Я отредактировал вопрос, чтобы сделать его более тестируемым. Как пройти? my_item на ссылки, извлеченные из Rule(LinkExtractor...) (Я переместил правила из инициализации spider, чтобы мне было легче это делать (используйте мета), но я все еще не могу это сделать.

Любая помощь высоко ценится

Я пытался использовать

    rules = (
        Rule(LinkExtractor(restrict_xpaths='//div[@class="r"]/a',allow='/dp',allow_domains='chewy.com'),
            process_request=lambda request:request.meta.update({'my_item':my_item}),callback='chewy'),
        Rule(LinkExtractor(restrict_xpaths='//div[@class="r"]/a',allow='/p/',allow_domains='homedepot.com')
            ,process_request=lambda request:request.meta.update({'my_item':my_item}),callback='homedepot')

        )

Это не дает ошибки, но страница не запрашивается

1 ответ

Ваш первый пример - неправильный код Python, как сообщает Python.

Ваш второй пример не работает, потому что ваш обратный вызов для process_request параметр Rule, lambda функция, возвращает None,

Если вы проверите документацию:

process_request является вызываемой или строкой (в этом случае будет использоваться метод из объекта-паука с таким именем), который будет вызываться при каждом запросе, извлеченном этим правилом, и должен возвращать запрос или None (чтобы отфильтровать запрос),

Это на самом деле не единственная причина, по которой это не работает. Чтобы использовать основанные на правилах экстракторы ссылок, вы должны:

  • Подкласс CrawlSpider, Из ваших примеров не ясно, делаете ли вы это.

  • Не переопределять parse метод в вашем подклассе, как вы делаете в настоящее время. Если start_urls не достаточно хорош для вас, используйте его в сочетании с parse_start_url,

  • Правила должны быть объявлены как атрибут класса. Вместо этого вы определяете их как переменные в методе вашего подкласса Spider. Это не сработает.

Пожалуйста, перечитайте документацию по CrawlSpider.

Что касается передачи значения из мета ответа в мета следующего запроса, у вас есть 2 варианта:

  • Переопределить ваш паук как Spider подкласс, а не CrawlSpider подкласс, вручную выполняя всю логику без экстракторов ссылок на основе правил.

    Это естественный шаг, когда общий паук, как CrawlSpider начинает чувствовать себя слишком ограничительным. Общие подклассы паука хороши для простых случаев использования, но всякий раз, когда вы сталкиваетесь с чем-то нетривиальным, вы должны рассмотреть вопрос о переходе на обычный Spider подкласс.

  • Дождитесь выхода Scrapy 1.7, что должно произойти в ближайшее время (вы можете использовать master ветвь Scrapy в то же время). Scrapy 1.7 представляет новый response параметр для process_request обратные вызовы, которые позволят вам сделать что-то вроде:


def my_request_processor(request, response):
    request.meta['item'] = response.meta['item']
    return request

class MySpider(CrawlSpider):

    # …

    rules = (
        Rule(
            LinkExtractor(
                restrict_xpaths='//div[@class="r"]/a',
                allow='/p/',
                allow_domains='homedepot.com'
            ),
            process_request=my_request_processor,
            callback='homedepot'
        )
    )

    # …
Другие вопросы по тегам