Scrapy не вызывает никакой другой функции после "__init__"

OS: Ubuntu 16.04 Stack – Scrapy 1.0.3 + Selenium Я довольно новичок в scrapy, и это может звучать очень просто, но у моего паука выполняется только « init ». Любой код / ​​функция после этого не вызывается, а паук просто останавливается.

class CancerForumSpider(scrapy.Spider): name = "mainpage_spider" allowed_domains = ["cancerforums.net"] start_urls = [ "http://www.cancerforums.net/forums/14-Prostate-Cancer-Forum" ] def __init__(self,*args,**kwargs): self.browser=webdriver.Firefox() self.browser.get("http://www.cancerforums.net/forums/14-Prostate-Cancer-Forum") print "----------------Going to sleep------------------" time.sleep(5) # self.parse() def __exit__(self): print "------------Exiting----------" self.browser.quit() def parse(self,response): print "----------------Inside Parse------------------" print "------------Exiting----------" self.browser.quit() 

Паук получает объект браузера, печатает «Going to sleep» и просто останавливается. Он не входит в функцию разбора.

введите описание изображения здесь

Ниже приведены содержимое журналов запуска:

—————- —————- —————- —————- Идти спать——————

2 Solutions collect form web for “Scrapy не вызывает никакой другой функции после "__init__"”

Есть несколько проблем, которые вам необходимо решить или знать:

  1. Вы не вызываете super() во время метода __init__ , поэтому ни одна из инициализации унаследованных классов не будет происходить. Scrapy ничего не сделает (например, вызывает метод parse() ), так как все настроено в scrapy.Spider .

  2. После исправления выше, ваш метод parse() будет вызываться Scrapy, но не будет работать на вашей веб-странице, выбранной на Selenium. Он не будет знать об этом вообще, и перейдет к повторной start_urls URL (на основе start_urls ). Очень вероятно, что эти два источника будут отличаться (часто резко).

  3. Вы собираетесь обойти почти все функции Scrapy, используя Selenium так, как вы. Все команды get() Selenium будут выполняться вне рамок Scrapy. Среднее ПО не будет применяться (файлы cookie, дросселирование, фильтрация и т. Д.), И никто из ожидаемых / созданных объектов (таких как request и response ) не будет заполнен данными, которые вы ожидаете.

Прежде чем исправить все это, вы должны рассмотреть несколько лучших вариантов / альтернатив:

  • Создайте промежуточное программное обеспечение загрузчика, которое обрабатывает все связанные с Selenium функциональные возможности. Попросите его перехватить объекты request прямо перед тем, как они попадут в загрузчик, заполнить новые объекты response и вернуть их для обработки пауком.
    Это не оптимально, поскольку вы эффективно создаете свой собственный загрузчик и короткозамкнутый Scrapy. Вам нужно будет повторно выполнить обработку любых желаемых настроек, которые обычно учитывает загрузчик, и заставить их работать с Selenium.
  • Ditch Selenium и использовать брандмауэр Splash HTTP и брандмауэра для обработки Javascript.
  • Ditch Scrapy все вместе и просто используйте Selenium и BeautifulSoup.

Scrapy полезен, когда вам приходится сканировать большое количество страниц. Селен обычно полезен для очистки, когда вам нужно иметь источник DOM после загрузки JS. Если это ваша ситуация, есть два основных способа объединения Selenium и Scrapy. Один из них – написать обработчик загрузки, как тот, который вы можете найти здесь .

Код выглядит так:

 # encoding: utf-8 from __future__ import unicode_literals from scrapy import signals from scrapy.signalmanager import SignalManager from scrapy.responsetypes import responsetypes from scrapy.xlib.pydispatch import dispatcher from selenium import webdriver from six.moves import queue from twisted.internet import defer, threads from twisted.python.failure import Failure class PhantomJSDownloadHandler(object): def __init__(self, settings): self.options = settings.get('PHANTOMJS_OPTIONS', {}) max_run = settings.get('PHANTOMJS_MAXRUN', 10) self.sem = defer.DeferredSemaphore(max_run) self.queue = queue.LifoQueue(max_run) SignalManager(dispatcher.Any).connect(self._close, signal=signals.spider_closed) def download_request(self, request, spider): """use semaphore to guard a phantomjs pool""" return self.sem.run(self._wait_request, request, spider) def _wait_request(self, request, spider): try: driver = self.queue.get_nowait() except queue.Empty: driver = webdriver.PhantomJS(**self.options) driver.get(request.url) # ghostdriver won't response when switch window until page is loaded dfd = threads.deferToThread(lambda: driver.switch_to.window(driver.current_window_handle)) dfd.addCallback(self._response, driver, spider) return dfd def _response(self, _, driver, spider): body = driver.execute_script("return document.documentElement.innerHTML") if body.startswith("<head></head>"): # cannot access response header in Selenium body = driver.execute_script("return document.documentElement.textContent") url = driver.current_url respcls = responsetypes.from_args(url=url, body=body[:100].encode('utf8')) resp = respcls(url=url, body=body, encoding="utf-8") response_failed = getattr(spider, "response_failed", None) if response_failed and callable(response_failed) and response_failed(resp, driver): driver.close() return defer.fail(Failure()) else: self.queue.put(driver) return defer.succeed(resp) def _close(self): while not self.queue.empty(): driver = self.queue.get_nowait() driver.close() 

Предположим, ваш скребок называется «скребок». Если вы поместили упомянутый код в файл с именем handlers.py в корневой папке «скребок», вы можете добавить в свой файл settings.py:

 DOWNLOAD_HANDLERS = { 'http': 'scraper.handlers.PhantomJSDownloadHandler', 'https': 'scraper.handlers.PhantomJSDownloadHandler', } 

Другой способ – написать промежуточное программное обеспечение для загрузки, как описано здесь . У промежуточного программного обеспечения для скачивания есть недостаток в предотвращении разработки некоторых ключевых функций, таких как кеш и повторы.

В любом случае, запуск веб-ресивера Selenium в начале паука Scrapy не является обычным способом.

  • Scrapy and Selenium: только лом две страницы
  • Использовать Scrapy для обхода локального XML-файла - Запустить адрес локального файла URL-адреса
  • Как очистить веб-сайт с помощью защиты сукури
  • Как сканировать данные с связанных веб-страниц на веб-странице, которую мы сканируем
  • Почему это непоследовательное поведение при использовании результатов печати на основе scrapy?
  • Вызов Scrapy из другого файла без потоковой передачи
  • Pass Scrapy Spider - список URL-адресов для обхода через .txt-файл
  • Экспорт csv-файла из scrapy (не через командную строку)
  • Python - лучший язык программирования в мире.