2016-03-06 49 views
1

我使用Scrapy shell來加載此網頁:Scrapy的XPath無法找到特定的DIV在網頁中

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

,並希望找到:

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

然而,返回[]。如果我在此網頁的Chrome瀏覽器中使用find,我可以找到3個"//div[@class='inline']"。這是一個錯誤?

回答

2

這頁的內聯的東西是</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']") 
+0

謝謝!這確實有效。但是,我不確定原因。例如,另一個類似的頁面'http:// goo.gl/J522yd'也有我想要的之後的內容,但可以通過'response.xpath(「// div [@ class ='inline']」)正確定位' 。 – entron

+0

當html被破壞時,所有投注都將關閉:)例如,工作的鏈接可能在某處存在一些開放標籤,導致解析器忽略''。另一個解決方案可能是嘗試Beautifulsoup。 'from bs4 import BeautifulSoup; soup = BeautifulSoup(response.body); results = soup.findAll(「div」,{「class」:「inline」})' 它可能能夠處理這種類型的更穩定的斷HTML。把scrapy和BeautifulSoup結合起來很簡單。 – neverlastn

+0

感謝您的建議! – entron

1

您還可以使用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> 
+0

另一個有效的方法。你可以通過'BeautifulSoup'使用'html5lib',以及'soup = BeautifulSoup(response.body,「html5lib」)'。有很多選擇:) – neverlastn