Динамические веб-сайты Python Scrapy

Я пытаюсь очистить очень простую веб-страницу с помощью Scrapy и ее селекторов xpath, но по какой-то причине мои селекторы не работают в Scrapy, но они работают в других утилитах xpath

Я пытаюсь разобрать этот фрагмент HTML:

<select id="chapterMenu" name="chapterMenu">

<option value="/111-3640-1/20th-century-boys/chapter-1.html" selected="selected">Chapter 1: Friend</option>

<option value="/111-3641-1/20th-century-boys/chapter-2.html">Chapter 2: Karaoke</option>

<option value="/111-3642-1/20th-century-boys/chapter-3.html">Chapter 3: The Boy Who Bought a Guitar</option>

<option value="/111-3643-1/20th-century-boys/chapter-4.html">Chapter 4: Snot Towel</option>

<option value="/111-3644-1/20th-century-boys/chapter-5.html">Chapter 5: Night of the Science Room</option>

</select>

Scrapy parse_item код:

def parse_item(self, response):
    itemLoader = XPathItemLoader(item=MangaItem(), response=response)
    itemLoader.add_xpath('chapter', '//select[@id="chapterMenu"]/option[@selected="selected"]/text()')
    return itemLoader.load_item()

Scrapy не извлекает никакого текста из этого, но если я получу один и тот же фрагмент кода xpath и html и запусту его здесь, он будет работать нормально.

если я использую этот xpath:

//select[@id="chapterMenu"]

Я получаю правильный элемент, но когда я пытаюсь получить доступ к параметрам внутри, он ничего не получает

2 ответа

Решение

Scrapy только делает запрос GET для URL, он не является веб-браузером и поэтому не может запускать JavaScript. Из-за одной только этой Scrapy будет недостаточно, чтобы пролистать динамические веб-страницы.

Кроме того, вам понадобится что-то вроде Selenium, которое в основном дает вам интерфейс к нескольким веб-браузерам и их функциям, одним из которых является возможность запускать JavaScript и получать HTML на стороне клиента.

Вот фрагмент того, как можно это сделать:

from Project.items import SomeItem
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.selector import Selector
from selenium import webdriver
import time

class RandomSpider(CrawlSpider):

    name = 'RandomSpider'
    allowed_domains = ['random.com']
    start_urls = [
        'http://www.random.com'
    ]

    rules = (
        Rule(SgmlLinkExtractor(allow=('some_regex_here')), callback='parse_item', follow=True),
    )

    def __init__(self):
        CrawlSpider.__init__(self)
        # use any browser you wish
        self.browser = webdriver.Firefox() 

    def __del__(self):
        self.browser.close()

    def parse_item(self, response):
        item = SomeItem()
        self.browser.get(response.url)
        # let JavaScript Load
        time.sleep(3) 

        # scrape dynamically generated HTML
        hxs = Selector(text=self.browser.page_source) 
        item['some_field'] = hxs.select('some_xpath')
        return item

Я думаю, что нашел веб-страницу, из которой вы хотите извлечь, и главы загружаются после выборки некоторых данных JSON, основанных на "манге" (который доступен в массиве Javascript на странице.

Таким образом, выборка глав заключается в создании конкретного запроса GET для конкретного /actions/selector/ конечная точка. Это в основном подражание тому, что делает движок вашего браузера Javascript.

Вы, вероятно, получаете лучшую производительность, используя эту технику, чем Selenium, но она включает (незначительный) анализ Javascript (никакой реальной интерпретации не требуется).

Другие вопросы по тегам