Python Scrapy动态网站

时间:2014-01-19 19:33:02

标签: python html 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>

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片段并运行它here它就可以了。

如果我使用这个xpath:

//select[@id="chapterMenu"]

我得到了正确的元素,但当我尝试访问其中的选项时,它没有得到任何东西

2 个答案:

答案 0 :(得分:4)

Scrapy只对URL进行GET请求,它不是Web浏览器,因此无法运行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

答案 1 :(得分:1)

我想我找到了你想要提取的网页,并且在获取一些JSON数据之后加载了这些章节,基于“mangaid”(可以在页面中的Javascript数组中找到。

因此,获取章节是向特定/actions/selector/端点发出特定GET请求的问题。它基本上模仿了浏览器的Javascript引擎正在做什么。

使用这种技术可能比Selenium获得更好的性能,但它确实涉及(次要)Javascript解析(不需要真正的解释)。