Скапировка не вызывает никакой другой функции после «__init__» -- python поле с участием python-2.7 поле с участием selenium поле с участием scrapy поле с участием scrapy-spider пол Связанный проблема

Scrapy not calling any other function after “__init__”


2
vote

проблема

русский

ОС: Ubuntu 16.04 Стек - Scrapy 1.0.3 + Selenium Я довольно новичок в Scrape, и это может звучать очень простое, но в моем пауке только « 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()   

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

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

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

------------------ внутри init ------------------ ------------------ Добраться спать --------------------------

Английский оригинал

OS: Ubuntu 16.04 Stack - Scrapy 1.0.3 + Selenium I'm pretty new to scrapy and this might sound very basic, But in my spider, only "init" is being getting executed. Any code/function after that is not getting called and thhe spider just halts.

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() 

The spider gets the browser object, prints "Going to sleep" and just halts. It doesn't go inside the parse function.

enter image description here

Following are the contents of the run logs:

----------------inside init---------------- ----------------Going to sleep------------------

</div
              
     
     

Список ответов

3
 
vote

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

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

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

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

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

    .
  • Создать промежуточное программное обеспечение для загрузки, которая обрабатывает все связанные функции «Selenium». Иметь ли он перехватывать <код> request объектов прямо до того, как они попадут в загрузку, заполните новый <код> __init__0 объектов и вернуть их для обработки пауком.
    Это не оптимально, так как вы эффективно создаете свой собственный загрузчик, а также Scrapy's Scraphy. Вам придется повторно реализовать обработку любых желаемых настроек. Загрузчик обычно учитывает и заставляет их работать с Selenium.
  • ditch selenium и используйте промежуточное программное обеспечение Splash Http и Scrapy-Splash для обработки JavaScript.
  • Грузовая ссадка все вместе и просто используйте Selenium и Beautifulsoup.
 

There are a few problems you need to address or be aware of:

  1. You're not calling super() during the __init__ method, so none of the inherited classes initialization is going to be happening. Scrapy won't do anything (like calling it's parse() method), as that all is setup in scrapy.Spider.

  2. After fixing the above, your parse() method will be called by Scrapy, but won't be operating on your Selenium-fetched webpage. It will have no knowledge of this whatsoever, and will go re-fetch the url (based on start_urls). It's very much likely that these two sources will differ (often drastically).

  3. You're going to be bypassing almost all of Scrapy's functionality using Selenium the way you are. All of Selenium's get()'s will be executed outside of the Scrapy framework. Middleware won't be applied (cookies, throttling, filtering, etc.) nor will any of the expected/created objects (like request and response) be populated with the data you expect.

Before you fix all of that, you should consider a couple of better options/alternatives:

  • Create a downloader middleware that handles all "Selenium" related functionality. Have it intercept request objects right before they hit the downloader, populate a new response objects and return them for processing by the spider.
    This isn't optimal, as you're effectively creating your own downloader, and short-circuiting Scrapy's. You'll have to re-implement the handling of any desired settings the downloader usually takes into account and make them work with Selenium.
  • Ditch Selenium and use the Splash HTTP and scrapy-splash middleware for handling Javascript.
  • Ditch Scrapy all together and just use Selenium and BeautifulSoup.
</div
 
 
1
 
vote

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

Код идет как:

 <код> __init__1  

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

 <код> __init__2  

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

В любом случае, запуск Webdriver Selenium в init of Scraphy Spider не является обычным способом.

 

Scrapy is useful when you have to crawl a big amount of pages. Selenium is normally useful for scraping when you need to have the DOM source after the JS was loaded. If that's your situation, there are two main ways to combine Selenium and Scrapy. One is to write a download handler, like the one you can find here.

The code goes as:

# 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() 

Suppose your scraper is called "scraper". If you put the mentioned code inside a file called handlers.py on the root of the "scraper" folder, then you could add to your settings.py:

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

Another way is to write a download middleware, as described here. The download middleware has the downside of preventing some key features from working out of the box, such as cache and retries.

In any case, starting the Selenium webdriver at the init of the Scrapy spider is not the usual way to go.

</div
 
 
 
 

Связанный проблема

51  Запросы Python «Пропасные зависимости от поддержки носков» при использовании SOCKS5 из терминала  ( Pythons requests missing dependencies for socks support when using socks5 fro ) 
Я пытаюсь взаимодействовать с API из My Python 2.7 Shell, используя пакет, который опирается на запросы Python. Вещь - это удаленный адрес блокируется моей се...

2  Добавьте номера в шестнадцатеричном базе без конвертации баз?  ( Add numbers in hexadecimal base without converting bases ) 
Мне нужно написать функцию, которая получает два числа в шестнадцатеричном базе, и вычисляет сумму обоих из них, мне не разрешено преобразовывать их в десятич...

0  После добавления клеток найдите мин и максимум пяти различных категорий в файле CSV  ( After appending cells find min and max of five different categories in a csv fi ) 
Привет всем У меня есть вопрос. Я просто сейчас изучаю мин и макс. У меня проблемы в нахождении мин и максимум пяти столбцов для каждой категории Вот, что...

2  Высокое использование ЦП в ткани 1.0.0  ( High cpu usage in fabric 1 0 0 ) 
в ткани 0,9, все работает нормально, но в 1.0.0, следующий скрипт ткани показывает 100% загрузку CPU в <Код> top : <код> from fabric.api import run def tes...

1  Нахождение корней с Scipy.Optimize.root  ( Finding roots with scipy optimize root ) 
Я пытаюсь найти root y функции, называемой f с помощью python. Вот мой код: <код> def f(y): w,p1,p2,p3,p4,p5,p6,p7 = y[:8] t1 = w - 0.500371726*...

1  Как мне позвонить в родительский класс в подклассе?  ( How do i call on a parent class in a subclass ) 
Мне нужно создать вызов несвязанного метода, чтобы установить имя и листья, и я не знаю, как. Любая помощь ценится. Мой код: <код> class Plant(object): ...

0  Объедините несколько столов для ответа JSON в Django Read Framework  ( Combine multiple tables for a json response in django rest framework ) 
Я использую Django Read Framework для моего serializers . Мне нужно создать веб-сервис, который сочетает в себе поля в трех таблицах и дает JSON. У меня ес...

5  Как я могу получить Mercurial для того, чтобы снова выдвигать коммиты?  ( How can i get mercurial to push commits again ) 
Я не знаю, что я ничего изменил и работаю Ubuntu 10.10. Mercurial работает нормально, а затем внезапно, когда я начал толкать сегодня утром, я начал получать ...

16  Как преобразовать шестигранную строку в шестнадцатеричный номер?  ( How to convert hex string to hex number ) 
У меня есть целое число в бывшем. 16 И я пытаюсь преобразовать этот номер в шестнадцатеричный номер. Я пытался достичь этого, используя функцию Hex, но всякий...

2  подмодул .POPEN отказывается запускать команду, хотя OS.System работает нормально  ( Submodules popen refuses to run a command even though os system works fine ) 
Всякий раз, когда я запускаю этот скрипт: <код> gcalctool0 Я постоянно получаю эту ошибку: <код> gcalctool1 Тем не менее, <код> gcalctool2 определе...

-4  Как суммировать значения при заворачивании аналогичного ключа, чтобы построить Dict  ( How to sum values when zipping similar key to build a dict ) 
У меня есть <код> A = [a, b, c, d, a, d, c] и <код> B=[1, 2, 3, 4, 5, 6, 7] Почему <код> dict(zip(A,B)) не возвращается <код> {'a': 6, 'b': 2, 'c': 10, '...

0  Почему этот сценарий Python работает на Ubuntu, но не распачин?  ( Why does this python script work on ubuntu but not raspbian ) 
Друг, и я создал следующий скрипт, использующий BeautifulSoup, чтобы получить HTML страницы работы, а затем добавить работу на массив, затем файл, затем отпра...

0  NameError: Имя «Домашние животные» не определены. Питон  ( Nameerror name pets is not defined python ) 
Это код, который я использую, но каждый раз, когда я пытаюсь запустить его, я получаю эту ошибку в терминале: <код> Traceback (most recent call last): Fil...

0  Запустите сценарий Python в колбу  ( Run python script into flask ) 
У меня есть настольное приложение для обнаружения лиц, написанных в сценарии Python, используя OpenCV и Numpy. Я хочу поставить эти файлы Python в колбу и зап...

9  От CVX до CVXPY или CVXOPT  ( From cvx to cvxpy or cvxopt ) 
Я пытался пройти какой-код из Matlab в Python. У меня такая же проблема с выпуклой оптимизацией, работающая на MATLAB, но у меня возникли проблемы, передавающ...

Связанный проблема

51  Запросы Python «Пропасные зависимости от поддержки носков» при использовании SOCKS5 из терминала 
2  Добавьте номера в шестнадцатеричном базе без конвертации баз? 
0  После добавления клеток найдите мин и максимум пяти различных категорий в файле CSV 
2  Высокое использование ЦП в ткани 1.0.0 
1  Нахождение корней с Scipy.Optimize.root 
1  Как мне позвонить в родительский класс в подклассе? 
0  Объедините несколько столов для ответа JSON в Django Read Framework 
5  Как я могу получить Mercurial для того, чтобы снова выдвигать коммиты? 
16  Как преобразовать шестигранную строку в шестнадцатеричный номер? 
2  подмодул .POPEN отказывается запускать команду, хотя OS.System работает нормально 
-4  Как суммировать значения при заворачивании аналогичного ключа, чтобы построить Dict 
0  Почему этот сценарий Python работает на Ubuntu, но не распачин? 
0  NameError: Имя «Домашние животные» не определены. Питон 
0  Запустите сценарий Python в колбу 
9  От CVX до CVXPY или CVXOPT