как использовать мета в правиле терапии - PullRequest
0 голосов
/ 11 июля 2019
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...) (я перенес правила из инициализациипаука, чтобы мне было легче делать (используйте мета), но я все еще не могу это сделать.

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

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

    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 Ответ

0 голосов
/ 17 июля 2019

Ваш первый пример - неправильный код 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 , что должно произойти в ближайшее время (тем временем вы можете использовать ветку Scrapy master).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'
        )
    )

    # …
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...