Большинство проблем решаемы, и у меня есть небольшой беспорядок. Однако я столкнулся с огромным препятствием на пути решения одной проблемы. Если сайт загружает таблицу лошадей и перечисляет текущие цены на ставки, этой информации нет ни в одном исходном файле. Подсказка заключается в том, что эти данные иногда бывают живыми, причем числа, очевидно, обновляются с какого-то удаленного сервера. В HTML на моем ПК просто есть дыра, где их серверы проталкивают все интересные данные, которые мне нужны.

Я думаю, что Java или Javascript — это ключ, который часто появляется.

Теперь мой опыт работы с динамическим веб-контентом низок, поэтому у меня возникли проблемы с тем, чтобы разобраться в этом.

Скребок — это просто механизм сравнения шансов. У некоторых сайтов есть API, но мне это нужно для тех, кто этого не делает. Я использую библиотеку scrapy с Python 2.7. Я прошу прощения, если этот вопрос слишком открытый. Короче говоря, мой вопрос: как можно использовать скрап для очистки этих динамических данных, чтобы я мог их использовать? Чтобы я мог в реальном времени обработать данные о коэффициентах ставок?

В нижней части рисунка видно, что я отфильтровал запрос до

Совет: журнал очищается каждый раз, когда вы загружаете страницу, в нижней части рисунка кнопка с черной точкой сохраняет журнал.

«2.0000» Menu->Tools->Developer Tools. Пакет Network позволяет видеть всю информацию о каждом запросе и ответе:

enter image description here

После анализа запросов и ответов вы можете смоделировать эти запросы от вашего веб-сканера и извлечь ценные данные. Во многих случаях будет проще получить ваши данные, чем анализировать HTML, потому что эти данные не содержат логику представления и отформатированы для доступа к коду javascript. XHR — это запросы, сделанные с помощью кода JavaScript.

Firefox имеет аналогичное расширение, оно называется

firebug

. Некоторые утверждают, что firebug еще более мощный, но мне нравится простота webkit. с запросом AJAX. Посмотрим на сайт rubin-kazan.ru

Вот простой пример scrapy Когда я анализирую исходный код страницы, я не вижу все эти сообщения, потому что веб-страница использует технологию AJAX. Но я могу с помощью Firebug от Mozilla Firefox (или аналогичного инструмента в других браузерах) проанализировать HTTP-запрос, который генерирует сообщения на веб-странице: rubin-kazan.ru Глядя на вывод

Все сообщения загружаются с помощью запроса AJAX. Моя цель — получить эти сообщения со всеми их атрибутами (автор, дата, …):

enter image description here

Когда я анализирую исходный код страницы, я не вижу все эти сообщения, потому что веб-страница использует технологию AJAX. Но я могу с помощью Firebug из Mozilla Firefox (или аналогичного инструмента в других браузерах) проанализировать HTTP-запрос, который генерирует сообщения на веб-странице:

enter image description here

Он не перезагружает всю страницу, а только части страницы, которые содержать сообщения. Для этого я нажимаю произвольное количество страниц внизу:

enter image description here

И я наблюдаю HTTP-запрос, который отвечает за тело сообщения:

enter image description here

После завершения я анализирую заголовки запроса (я должен процитировать, что этот URL я извлеку из исходной страницы из раздела var, см. Код ниже) :

enter image description here

обычные ключи в порядке вставки

enter image description here

И содержание ответа, которое представляет собой файл JSON:

enter image description here

, которая представляет все информация, которую я ищу.

С сегодняшнего дня я должен применить все эти знания в скрапе. Давайте для этого определим паука:

class spider(BaseSpider):
    name = 'RubiGuesst'
    start_urls = ['http://www.rubin-kazan.ru/guestbook.html']

    def parse(self, response):
        url_list_gb_messages = re.search(r'url_list_gb_messages="(.*)"', response.body).group(1)
        yield FormRequest('http://www.rubin-kazan.ru'   url_list_gb_messages, callback=self.RubiGuessItem,
                          formdata={'page': str(page   1), 'uid': ''})

    def RubiGuessItem(self, response):
        json_file = response.body

закрытии JavaScript внутри циклов — простой практический пример — переполнение стека parse у меня есть ответ на первый запрос. В RubiGuessItem У меня есть файл JSON со всей информацией.

Как получить все возможные совпадения для строки

Обновлено 5 сентября 2010 г.

Несколько замечаний:

  • 2

  • Это довольно мощный инструмент, потому что теперь у вас есть весь готовый DOM, доступный для сканирования, и вы все равно можете использовать все приятное сканирование особенности в Scrapy. Это, конечно, сделает медленное сканирование, но в зависимости от того, насколько вам нужен обработанный DOM, это может стоить ожидания. Метод

    from scrapy.contrib.spiders import CrawlSpider, Rule
    from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
    from scrapy.selector import HtmlXPathSelector
    from scrapy.http import Request
    
    from selenium import selenium
    
    class SeleniumSpider(CrawlSpider):
        name = "SeleniumSpider"
        start_urls = ["http://www.domain.com"]
    
        rules = (
            Rule(SgmlLinkExtractor(allow=('.html', )), callback='parse_page',follow=True),
        )
    
        def __init__(self):
            CrawlSpider.__init__(self)
            self.verificationErrors = []
            self.selenium = selenium("localhost", 4444, "*chrome", "http://www.domain.com")
            self.selenium.start()
    
        def __del__(self):
            self.selenium.stop()
            print self.verificationErrors
            CrawlSpider.__del__(self)
    
        def parse_page(self, response):
            item = Item()
    
            hxs = HtmlXPathSelector(response)
            #Do some XPath selection with Scrapy
            hxs.select('//div').extract()
    
            sel = self.selenium
            sel.open(response.url)
    
            #Wait for javscript to load in Selenium
            time.sleep(2.5)
    
            #Do some crawling of javascript created content with Selenium
            sel.get_text("//div")
            yield item
    
    # Snippet imported from snippets.scrapy.org (which no longer works)
    # author: wynbennett
    # date  : Jun 21, 2011
    

Ссылка: http://snipplr.com/view/66998/

Еще одно решение — реализовать обработчик загрузки или промежуточное программное обеспечение обработчика загрузки. (см. , но это через много лет. для получения дополнительной информации о промежуточном программном обеспечении загрузчика). Ниже приведен пример класса, в котором используется селен с безголовым веб-драйвером phantomjs:

1) Определите класс в middlewares.py Вы можете использовать следующее

from selenium import webdriver
from scrapy.http import HtmlResponse

class JsDownload(object):

    @check_spider_middleware
    def process_request(self, request, spider):
        driver = webdriver.PhantomJS(executable_path='D:phantomjs.exe')
        driver.get(request.url)
        return HtmlResponse(request.url, encoding='utf-8', body=driver.page_source.encode('utf-8'))

2) add JsDownload() для переменной DOWNLOADER_MIDDLEWARE в settings.py:

DOWNLOADER_MIDDLEWARES = {'MyProj.middleware.MiddleWareModule.MiddleWareClass': 500}

3) Интегрировать . Расшифровка тела ответа даст вам желаемый результат. HTMLResponse, поэтому браузер не сможет загрузить новую страницу. your_spider.py Необязательное дополнение:

class Spider(CrawlSpider):
    # define unique name of spider
    name = "spider"

    start_urls = ["https://www.url.de"] 

    def parse(self, response):
        # initialize items
        item = CrawlerItem()

        # store data as items
        item["js_enabled"] = response.body.decode("utf-8") 

для работы оболочки, как минимум, должны иметь все пауки:
Мне нужна была возможность сообщать различным паукам, какое промежуточное программное обеспечение использовать, поэтому я реализовал эту оболочку:

def check_spider_middleware(method):
@functools.wraps(method)
def wrapper(self, request, spider):
    msg = '%%s %s middleware step' % (self.__class__.__name__,)
    if self.__class__ in spider.middleware:
        spider.log(msg % 'executing', level=log.DEBUG)
        return method(self, request, spider)
    else:
        spider.log(msg % 'skipping', level=log.DEBUG)
        return None

return wrapper

Основное преимущество такой реализации, а не паука, заключается в том, что вы в конечном итоге делаете только один запрос. Например, в решении A T: обработчик загрузки обрабатывает запрос, а затем передает ответ пауку. Затем паук делает новый запрос в функции parse_page — это два запроса на один и тот же контент.

middleware = set([])

, чтобы включить промежуточное ПО:

middleware = set([MyProj.middleware.ModuleName.ClassName])

Advantage:
Есть рабочий пример

, я использовал специальное промежуточное ПО для загрузчика, но мне это не очень понравилось, так как мне не удалось заставить кэш работать с ним.

Лучшим подходом было реализовать пользовательский обработчик загрузки.

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

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

И вуаля, анализируемый DOM JS с кэш-памятью, повторяет попытки, и т. д.

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

как можно использовать скрап для очистки этих динамических данных, чтобы я мог их использовать?

Ознакомьтесь с сообщением в блоге от команды Scrapy

46 = & gt ; (Delete) ; { *} Также учтите, что

УДАЛЕНИЕ НЕПРЕРЫВНЫХ СТРАНИЦ ПРОКРУТКИ . В этом примере записывается http://spidyquotes.herokuapp.com/scroll веб-сайт с бесконечной прокруткой. Идея состоит в том, чтобы

использовать Инструменты разработчика вашего браузера и замечать запросы AJAX, а затем на основе этой информации создавать запросы для Scrapy Я обрабатываю запрос ajax с помощью Selenium и веб-драйвера Firefox. Это не так быстро, если вам нужен сканер как демон, но гораздо лучше, чем любое ручное решение. Я написал краткое руководство Глядя на вывод

import json
import scrapy


class SpidyQuotesSpider(scrapy.Spider):
    name = 'spidyquotes'
    quotes_base_url = 'http://spidyquotes.herokuapp.com/api/quotes?page=%s'
    start_urls = [quotes_base_url % 1]
    download_delay = 1.5

    def parse(self, response):
        data = json.loads(response.body)
        for item in data.get('quotes', []):
            yield {
                'text': item.get('text'),
                'author': item.get('author', {}).get('name'),
                'tags': item.get('tags'),
            }
        if data['has_next']:
            next_page = data['page']   1
            yield scrapy.Request(self.quotes_base_url % next_page)

для справки говорится, что Во-первых,

Qwerty’s answer

Существует два подхода к анализу: вид веб-сайтов.

вы можете использовать

Scrapy splash, git splash включает Во-вторых,

Как все утверждают, следя за

, да, Вы можете найти вызов API, который извлекает данные, и имитация вызова в вашем пауке-скрапе может помочь вам получить нужные данные. network calls javascript — при нажатии кнопки «Назад» происходит событие кросс-браузерной загрузки? — Переполнение стека