Scrapy - 选择器



描述

当您抓取网页时,需要使用称为选择器的机制来提取HTML源代码的特定部分,这可以通过使用XPath或CSS表达式来实现。选择器基于lxml库构建,该库使用Python语言处理XML和HTML。

使用以下代码片段来定义选择器的不同概念:

<html>
   <head>
      <title>My Website</title>
   </head>
   
   <body>
      <span>Hello world!!!</span>
      <div class = 'links'>
         <a href = 'one.html'>Link 1<img src = 'image1.jpg'/></a>
         <a href = 'two.html'>Link 2<img src = 'image2.jpg'/></a>
         <a href = 'three.html'>Link 3<img src = 'image3.jpg'/></a>
      </div>
   </body>
</html>

构建选择器

您可以通过传递文本TextResponse对象来构建选择器类实例。根据提供的输入类型,选择器将选择以下规则:

from scrapy.selector import Selector 
from scrapy.http import HtmlResponse

使用上面的代码,您可以从文本构建:

Selector(text = body).xpath('//span/text()').extract() 

它将显示结果为:

[u'Hello world!!!'] 

您可以从响应构建:

response = HtmlResponse(url = 'http://mysite.com', body = body) 
Selector(response = response).xpath('//span/text()').extract()

它将显示结果为:

[u'Hello world!!!']

使用选择器

使用上面的简单代码片段,您可以构建XPath来选择在title标签中定义的文本,如下所示:

>>response.selector.xpath('//title/text()')

现在,您可以使用.extract()方法提取文本数据,如下所示:

>>response.xpath('//title/text()').extract()

它将产生以下结果:

[u'My Website']

您可以显示所有元素的名称,如下所示:

>>response.xpath('//div[@class = "links"]/a/text()').extract() 

它将显示元素为:

Link 1
Link 2
Link 3

如果要提取第一个元素,则使用.extract_first()方法,如下所示:

>>response.xpath('//div[@class = "links"]/a/text()').extract_first()

它将显示元素为:

Link 1

嵌套选择器

使用上面的代码,您可以嵌套选择器以使用.xpath()方法显示页面链接和图像源,如下所示:

links = response.xpath('//a[contains(@href, "image")]') 

for index, link in enumerate(links): 
   args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract()) 
   print 'The link %d pointing to url %s and image %s' % args 

它将显示结果为:

Link 1 pointing to url [u'one.html'] and image [u'image1.jpg']
Link 2 pointing to url [u'two.html'] and image [u'image2.jpg']
Link 3 pointing to url [u'three.html'] and image [u'image3.jpg']

使用正则表达式的选择器

Scrapy允许使用正则表达式提取数据,它使用.re()方法。从上面的HTML代码中,我们将提取图像名称,如下所示:

>>response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:\s*(.*)')

以上代码将显示图像名称为:

[u'Link 1', 
u'Link 2', 
u'Link 3'] 

使用相对XPath

当您使用以/开头的XPath时,嵌套选择器和XPath与文档的绝对路径相关,而不是选择器的相对路径。

如果要提取<p>元素,则首先获取所有div元素:

>>mydiv = response.xpath('//div')

接下来,您可以通过在XPath前面添加一个点作为.//p来提取内部的所有'p'元素,如下所示:

>>for p in mydiv.xpath('.//p').extract() 

使用EXSLT扩展

EXSLT是一个社区,它发布对XSLT(可扩展样式表语言转换)的扩展,该语言将XML文档转换为XHTML文档。您可以使用XPath表达式中注册的命名空间使用EXSLT扩展,如下表所示:

序号 前缀 & 用途 命名空间
1

re

正则表达式

http://exslt.org/regexp/index.html

2

set

集合操作

http://exslt.org/set/index.html

您可以在上一节中查看使用正则表达式提取数据的简单代码格式。

有一些XPath技巧,在Scrapy选择器中使用XPath时非常有用。更多信息,请点击此链接

广告