【问题标题】:Scrapy xpath fail to find certain div in a webpageScrapy xpath 无法在网页中找到某些 div
【发布时间】:2016-06-19 20:40:43
【问题描述】:

我使用 Scrapy shell 来加载这个网页:

scrapy shell "http://goo.gl/VMNMuK"

并想找到:

response.xpath("//div[@class='inline']")

但是,它返回 []。如果我在此网页的 chrome 检查中使用 find,我可以找到 "//div[@class='inline']" 中的 3 个。这是一个错误吗?

【问题讨论】:

    标签: xpath scrapy lxml


    【解决方案1】:

    此页面的内联内容位于</body></html>...之后...

    </body></html>
    <script type="text/javascript">
    var cpro_id="u2312677";
    ...
    

    这里有一些事情可以尝试:

    rest = response.body[response.body.find('</html>')+8:]
    from scrapy.selector import Selector
    Selector(text=rest).xpath("//div[@class='inline']")
    

    【讨论】:

    • 谢谢!这确实有效。但是,我不确定原因。例如,另一个类似的页面http://goo.gl/J522yd
    【解决方案2】:

    您还可以使用html5lib 来解析响应正文,例如work on an lxml document using lxml.html.html5parser。在下面的示例 scrapy shell 会话中,我必须使用 namespaces 来使用 XPath:

    $ scrapy shell http://chuansong.me/n/2584954
    2016-03-07 12:06:42 [scrapy] INFO: Scrapy 1.0.5 started (bot: scrapybot)
    2016-03-07 12:06:44 [scrapy] DEBUG: Crawled (200) <GET http://chuansong.me/n/2584954> (referer: None)
    In [1]: response.xpath('//div[@class="inline"]')
    Out[1]: []
    
    In [2]: response.xpath('//*[@class="inline"]')
    Out[2]: []
    
    In [3]: response.xpath('//html')
    Out[3]: [<Selector xpath='//html' data=u'<html lang="zh-CN">\n<head>\n<meta http-eq'>]
    
    In [4]: from lxml.html import tostring, html5parser
    
    In [5]: dochtml5 = html5parser.document_fromstring(response.body_as_unicode())
    
    In [6]: type(dochtml5)
    Out[6]: lxml.etree._Element
    
    In [7]: dochtml5.xpath('//div[@class="inline"]')
    Out[7]: []
    
    In [8]: dochtml5.xpath('//html:div[@class="inline"]', namespaces={"html": "http://www.w3.org/1999/xhtml"})
    Out[8]: 
    [<Element {http://www.w3.org/1999/xhtml}div at 0x7f858cfe3998>,
     <Element {http://www.w3.org/1999/xhtml}div at 0x7f858cf691b8>,
     <Element {http://www.w3.org/1999/xhtml}div at 0x7f858cf73680>]
    
    In [9]: for div in dochtml5.xpath('//html:div[@class="inline"]', namespaces={"html": "http://www.w3.org/1999/xhtml"}):
        print tostring(div)
       ....:     
    <html:div xmlns:html="http://www.w3.org/1999/xhtml" class="inline">
    <html:span>&#26032;&#28010;&#21517;&#21338;&#12289;&#30021;&#38144;&#20070;&#20316;&#23478;&#29579;&#29667;&#30340;&#21407;&#21019;&#33258;&#23186;&#20307;&#65292;&#8220;&#33433;&#33993;&#26641;&#19979;&#8221;&#30340;&#21448;&#19968;&#29255;&#26032;&#22825;&#22320;&#65292;&#24895;&#20320;&#32654;&#20029;&#20248;&#38597;&#22320;&#36208;&#36807;&#20840;&#19990;&#30028;&#12290;</html:span>
    </html:div>
    
    <html:div xmlns:html="http://www.w3.org/1999/xhtml" class="inline">
    <html:img src="http://q.chuansong.me/beauties-4.jpg" alt="&#32654;&#20154;&#30340;&#24213;&#27668; &#24494;&#20449;&#20108;&#32500;&#30721;" height="210px" width="210px"></html:img>
    </html:div>
    
    <html:div xmlns:html="http://www.w3.org/1999/xhtml" class="inline">
    <html:script src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" async=""></html:script>
    <html:ins style="display:inline-block;width:210px;height:210px" data-ad-client="ca-pub-0996811467255783" class="adsbygoogle" data-ad-slot="2990020277"></html:ins>
    <html:script>(adsbygoogle = window.adsbygoogle || []).push({});</html:script>
    </html:div>
    

    【讨论】:

    • 另一种有效的方法。您可以通过BeautifulSoup 使用html5lib 以及soup = BeautifulSoup(response.body, "html5lib")。有很多选择:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    相关资源
    最近更新 更多