2014-01-19 58 views
1

我想在Scrapy和它的xpath选择器的帮助下刮一个非常简单的网页,但由于某些原因,我有选择器不能在Scrapy中工作,但他们在其他xpath实用程序中工作Python Scrapy动态网站

我试图解析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不会从该提取任何文字,但如果我得到的SAM e xpath和html代码片段并运行它here它工作得很好。

如果我用这个XPath:

//select[@id="chapterMenu"] 

我得到正确的元素,但是当我尝试访问的选项里面它不会得到任何

+0

您的XPath对我来说看起来不错,通常Scrapy中的XPath对我来说工作正常。我会通过get_value检查使用XPath的结果。如果你得到正确的结果,错误发生在映射端。如果该值错误,则更容易实验并追踪XPath出了什么问题。我也会尝试摆脱主要的/ /这可能会导致意外的结果,在最小的HTML代码的变化的情况下。 – Achim

+0

如果我使用这个xpath:// select [@ id =“chapterMenu”]我得到正确的元素,但是当我尝试访问里面的选项没有得到任何东西 – arnm

+0

好吧所以我认为这可能是一个JavaScript问题,因为当我显示select标签为空的响应,但是当我在浏览器中查看源代码时,所有选项都存在 – arnm

回答

4

Scrapy不仅会为URL的GET请求,它不是一个Web浏览器,因此无法运行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 
1

我想我找到你想提取网页,以及章节获取一些JSON数据加载后的基础上, “mangaid”(即在网页JavaScript数组可用。

因此抓取章节中做出具体GET请求到特定/actions/selector/端点的问题。它基本上是模仿你的浏览器的Javascript引擎在做什么。

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

+0

好找!我可能会以这种方式结束,但这似乎更有可能导致抓取程序更容易中断,因为JavaScript现在也被添加到解析中。 – arnm

+0

好点@AlexeiNunez。这通常是易于维护和性能之间的折衷。你的来电。 –