2016-03-06 5 views
1

я использовал Scrapy оболочку, чтобы загрузить эту страницу:Scrapy XPath не найти определенный DIV на веб-странице

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

и хочу найти:

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

Однако, она возвращает []. Если я использую find in chrome для проверки этой веб-страницы, я могу найти 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 с большей стабильностью. Тривиально комбинировать скрипичные и 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

Еще один действительный подход. Вы можете использовать 'html5lib' через' BeautifulSoup', а также с 'soup = BeautifulSoup (response.body," html5lib ")'. Есть много вариантов :) – neverlastn