Python Scrapy 动态网站

arn*_*rnm 1 html python xml xpath 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>
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

Scrapy 不会从中提取任何文本,但是如果我得到相同的 xpath 和 html 片段并在此处运行它它就可以正常工作。

如果我使用这个 xpath:

//select[@id="chapterMenu"]
Run Code Online (Sandbox Code Playgroud)

我得到了正确的元素,但是当我尝试访问里面的选项时,它什么也没得到

arn*_*rnm 5

Scrapy 只对 url 执行 GET 请求,它不是网络浏览器,因此无法运行 JavaScript。由于这个 Scrapy 本身不足以抓取动态网页。

此外,您将需要像 Selenium 这样的东西,它基本上为您提供了几个 Web 浏览器及其功能的界面,其中之一是能够运行 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
Run Code Online (Sandbox Code Playgroud)