我正在尝试使用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]
的相同简短结果有没有想过为什么会这样,我怎样才能提取所需的数据呢?
答案 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正文中不存在,因此数字更高。