为什么response.xpath('// html')的结果与response.body不同?

时间:2014-11-16 10:46:28

标签: python xpath scrapy response

我正在尝试使用scrapy解析此页面 http://mobileshop.ae/one-x

我需要提取产品的链接。 问题是response.body结果中的链接是可用的,但是如果你尝试response.xpath('// body')则不可用.extract()

response.body和response.xpath('// body')的结果不同。

>>> body = response.body
>>> body_2 = response.xpath('//html').extract()[0]
>>> len(body)
238731
>>> len(body_2)
67520

response.xpath('。')。extract()[0]

的相同简短结果

有没有想过为什么会这样,我怎样才能提取所需的数据呢?

2 个答案:

答案 0 :(得分:3)

所以,这里的问题是该页面中的许多格式错误的内容,包括几个未封闭的标签。解决此问题的一种方法是使用lxml's soupparser来解析格式不正确的内容(使用BeautifulSoup),并使用它构建一个Scrapy Selector。

scrapy shell http://mobileshop.ae/one-x的示例会话:

>>> from lxml.html import soupparser
>>> from scrapy import Selector
>>> sel = Selector(_root=soupparser.fromstring(response.body))
>>> sel.xpath('//h4[@class="name"]/a').extract()
[u'<a href="http://mobileshop.ae/one-x/htc-one-x-16gb-gray">HTC One X 3G 16GB Grey</a>',
 u'<a href="http://mobileshop.ae/one-x/htc-one-x-16gb-white">HTC One X 3G 16GB White</a>',
 u'<a href="http://mobileshop.ae/one-x/htc-one-x-32gb-gray">HTC One X 3G 32GB Grey</a>',
 u'<a href="http://mobileshop.ae/one-x/htc-one-x-32gb-white">HTC One X 3G 32GB White</a>']

请注意,使用BeautifulSoup解析器比lxml的默认解析器慢很多。你可能只想在真正需要它的地方这样做。

答案 1 :(得分:0)

Response.xpath("//body")会返回响应中包含的body of 'html' element,而response.body会返回整个HTTP响应的正文(or message-body)(因此所有html都会响应,包括head&amp; body元素)。

Response.xpath("//body")实际上是将HTTP响应的主体转换为可以使用xpath导航的Selector对象的快捷方式。

你需要的链接包含在html元素体中,它们实际上不能在其他任何地方,我不确定你为什么建议它们不在那里。 response.xpath("//body//a/@href")将为您提供页面上的所有链接,您可能需要创建适当的xpath,仅选择您需要的链接。

您在示例中提到的response.xpath("//body")的长度是因为您的第一个示例len(response.xpath('//body').extract())返回html文档中的body元素数,response.xpath.extract()返回匹配的元素列表XPath的。文档中只有一个正文。在你的第二个例子len(response.xpath('//body')).extract()[0])中,你实际上是将body元素作为字符串,并且你得到字符串的长度(正文中包含的字符数)。 len(response.body)还为整个HTTP响应中的字符数量提供了数字,因为html HEAD包含大量脚本和样式表,而这些字符在HTML正文中不存在,因此数字更高。