Scrapy 选择器

在抓取网页时,您需要使用称为 选择器 的机制,通过使用XPath或CSS表达式来提取HTML源代码的某个部分。

选择器建立在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以选择标题标签中定义的文本,如下所示:

>>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']

 

使用相对XPaths

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

如果你想提取 元素,那么首先获得所有div元素:

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

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

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

 

使用EXSLT扩展

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

Sr.No 前缀和用法 命名空间
1 re 常用表达 [http://exslt.org/regexp/index.html](http://exslt.org/regexp/index.html)
2 set 设置操作 [http://exslt.org/set/index.html](http://exslt.org/set/index.html)

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