Невозможно передать пустой URL-адрес через скрап-конвейер

У меня есть список объектов данных, каждый из которых содержит URL-адрес для очистки. Некоторые из этих URL-адресов недействительны, но я все же хочу, чтобы объект данных провалился, чтобы достичь конвейеров элементов.

После ответа @tomáš-linhart я понял, что использование промежуточного программного обеспечения в этом случае не сработает, поскольку в первую очередь скрапи не позволит мне создать объект запроса.

Альтернативой является возврат элемента вместо запроса, если URL-адрес недействителен.

Ниже приведен мой код:

def start_requests(self):
        rurls = json.load(open(self.data_file))
        for data in rurls[:100]:
            url = data['Website'] or ''
            rid = data['id']

            # skip creating requests for invalid urls
            if not (url and validators.url(url)):
                yield self.create_item(rid, url)
                continue

            # create request object
            request_object = scrapy.Request(url=url, callback=self.parse, errback=self.errback_httpbin)

            # populate request object
            request_object.meta['rid'] = rid

            self.logger.info('REQUEST QUEUED for RID: %s', rid)
            yield request_object

Приведенный выше код выдает ошибку, как показано. Больше, чем ошибка, я не уверен, как отследить происхождение проблемы. :(

2017-09-22 12:44:38 [scrapy.utils.signal] ERROR: Error caught on signal handler: <bound method RefererMiddleware.request_scheduled of <scrapy.spidermiddlewares.referer.RefererMiddleware object at 0x10f603ef0>>
Traceback (most recent call last):
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/utils/signal.py", line 30, in send_catch_log
    *arguments, **named)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/pydispatch/robustapply.py", line 55, in robustApply
    return receiver(*arguments, **named)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/spidermiddlewares/referer.py", line 343, in request_scheduled
    redirected_urls = request.meta.get('redirect_urls', [])
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/item.py", line 74, in __getattr__
    raise AttributeError(name)
AttributeError: meta
Unhandled Error
Traceback (most recent call last):
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/commands/crawl.py", line 58, in run
    self.crawler_process.start()
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/crawler.py", line 285, in start
    reactor.run(installSignalHandlers=False)  # blocking call
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/twisted/internet/base.py", line 1243, in run
    self.mainLoop()
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/twisted/internet/base.py", line 1252, in mainLoop
    self.runUntilCurrent()
--- <exception caught here> ---
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/twisted/internet/base.py", line 878, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/utils/reactor.py", line 41, in __call__
    return self._func(*self._a, **self._kw)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/core/engine.py", line 135, in _next_request
    self.crawl(request, spider)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/core/engine.py", line 210, in crawl
    self.schedule(request, spider)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/core/engine.py", line 216, in schedule
    if not self.slot.scheduler.enqueue_request(request):
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/core/scheduler.py", line 54, in enqueue_request
    if not request.dont_filter and self.df.request_seen(request):
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/item.py", line 74, in __getattr__
    raise AttributeError(name)
builtins.AttributeError: dont_filter

2017-09-22 12:44:38 [twisted] CRITICAL: Unhandled Error
Traceback (most recent call last):
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/commands/crawl.py", line 58, in run
    self.crawler_process.start()
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/crawler.py", line 285, in start
    reactor.run(installSignalHandlers=False)  # blocking call
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/twisted/internet/base.py", line 1243, in run
    self.mainLoop()
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/twisted/internet/base.py", line 1252, in mainLoop
    self.runUntilCurrent()
--- <exception caught here> ---
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/twisted/internet/base.py", line 878, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/utils/reactor.py", line 41, in __call__
    return self._func(*self._a, **self._kw)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/core/engine.py", line 135, in _next_request
    self.crawl(request, spider)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/core/engine.py", line 210, in crawl
    self.schedule(request, spider)
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/core/engine.py", line 216, in schedule
    if not self.slot.scheduler.enqueue_request(request):
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/core/scheduler.py", line 54, in enqueue_request
    if not request.dont_filter and self.df.request_seen(request):
  File "/myhome/.virtualenvs/myproj/lib/python3.5/site-packages/scrapy/item.py", line 74, in __getattr__
    raise AttributeError(name)
builtins.AttributeError: dont_filter

person comiventor    schedule 22.09.2017    source источник


Ответы (2)


Вы не можете достичь цели, используя свой текущий подход, так как ошибка, которую вы получаете, возникает в конструкторе Request, см. http/request/__init__.py#L61" rel="nofollow noreferrer">код.

Во всяком случае, я не понимаю, почему вы вообще хотите сделать это таким образом. На основании вашего требования:

У меня есть список объектов данных, каждый из которых содержит URL-адрес для очистки. Некоторые из этих URL-адресов недействительны, но я все же хочу, чтобы объект данных провалился, чтобы достичь конвейеров элементов.

Если я правильно понимаю, у вас уже есть полный элемент (объект данных в вашей терминологии), и вы просто хотите, чтобы он прошел через конвейеры элементов. Затем выполните проверку URL-адреса в пауке, и если он недействителен, просто отдайте элемент вместо того, чтобы запрашивать URL-адрес, который он содержит. Нет необходимости в промежуточном программном обеспечении для пауков.

person Tomáš Linhart    schedule 22.09.2017
comment
Я пытался вернуть элемент в методе start_requests, но получаю ошибку AttributeError: meta и builtins.AttributeError: dont_filter - person comiventor; 22.09.2017
comment
Я имел в виду отдать предмет. позвольте мне обновить мой оригинальный пост - person comiventor; 22.09.2017
comment
Затем выполните проверку URL-адреса в пауке, и если он недействителен, просто отдайте элемент вместо того, чтобы запрашивать URL-адрес, который он содержит. Я не уверен, где я могу получить элемент вместо запроса. Не могли бы вы указать пример кода? Единственное место, где я могу получить оба, - это функция разбора, что означает, что мне придется подделать как минимум 1 запрос. - person comiventor; 03.10.2017

Вы не можете получить объект Item из метода start_requests. Только объект запроса.

person Verz1Lka    schedule 22.09.2017
comment
Я знал эту часть, но не мог понять, на что указывает Томас. Он говорит, сделайте проверку URL-адреса в пауке, и если он недействителен, просто отдайте элемент вместо того, чтобы запрашивать URL-адрес, который он содержит. Не знаете, как можно этого добиться? - person comiventor; 23.09.2017