Scrapy 选择器
当我们抓取网页时,需要使用称为选择器的机制提取 HTML 源的特定部分,该机制通过使用 XPath
或 CSS
表达式来实现。 选择器建立在 lxml 库之上,它以 Python 语言处理 XML 和 HTML。
使用以下代码片段来定义选择器的不同概念
<html>
<head>
<title> 迹忆客 </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']
使用相对 XPath
当我们使用以 /
开头的 XPath 时,嵌套选择器和 XPath 与文档的绝对路径相关,而不是选择器的相对路径。
如果要提取 <p>
元素,那么首先获取所有div元素
mydiv = response.xpath('//div')
接下来,我们可以提取其中的所有“p”元素,方法是在 XPath 前加上一个点作为 .//p
的前缀,如下所示
for p in mydiv.xpath('.//p').extract()
使用 EXSLT 扩展
EXSLT 是一个发布 XSLT(可扩展样式表语言转换)扩展的社区,可将 XML 文档转换为 XHTML 文档。 我们可以将 EXSLT 扩展与 XPath 表达式中已注册的命名空间一起使用,如下表所示
序号 | 前缀 | 用法 | 命名空间 |
---|---|---|---|
1 | re | 正则表达式 | http://exslt.org/regexp/index.html |
2 | set | set 操作 | http://exslt.org/set/index.html |
我们可以查看上一节使用正则表达式提取数据的简单代码格式。
有一些 XPath 技巧,在将 XPath 与 Scrapy 选择器一起使用时很有用。 有关更多信息,请单击此链接