Scrapy框架中Selector(选择器)的使用

用 Python 提取 HTML 源代码数据有很多现成的库,比如 lxml、BeautifulSoup、pyquery 等,当然如果会用正则表达式的话就不用在意这些了。而 Scrapy 框架则自带了专门的选择器 Selector,功能十分强大,并且可以根据输入类型自动选择最佳的解析规则。


直接使用

针对一段 HTML 代码,我们可以用如下方式构建 Selector 对象来提取数据:

>>> from scrapy.selector import Selector
>>> body = '<html><body><span>csdn</span></body></html>'
>>> Selector(text=body).xpath('//span/text()').get()
'csdn'

把 Scrapy 中的 Selector 单独拿出来,构建的时候传入 text 参数,就生成了一个 Selector 选择器对象,然后就可以调用 xpath()、css() 等方法来提取数据了。


下面将讲解使用选择器的用法,下面是用于测试的HTML代码:

<html>
	<head>
		<base href='http://example.com/' />
		<title>Example website</title>
	</head>
	<body>
		<div id='images'>
			<a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
			<a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
			<a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
			<a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
			<a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
		</div>
	</body>
</html>

构造响应:

>>> scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html

Scrapy 发起了一次请求,然后把一些可操作的变量传递给我们,如request、response 等,而页面源码就是上面的 HTML 代码,并把内容赋值给 response


XPath选择器

先展示几个实例:

>>> result = response.selector.xpath('//a')
>>> result
[<Selector xpath='//a' data='<a href="image1.html">Name: My image 1 <'>,
 <Selector xpath='//a' data='<a href="image2.html">Name: My image 2 <'>,
 <Selector xpath='//a' data='<a href="image3.html">Name: My image 3 <'>,
 <Selector xpath='//a' data='<a href="image4.html">Name: My image 4 <'>,
 <Selector xpath='//a' data='<a href="image5.html">Name: My image 5 <'>]
>>> type(result)
scrapy.selector.unified.SelectorList
>>> result.xpath('./img')
[<Selector xpath='./img' data='<img src="image1_thumb.jpg">'>,
 <Selector xpath='./img' data='<img src="image2_thumb.jpg">'>,
 <Selector xpath='./img' data='<img src="image3_thumb.jpg">'>,
 <Selector xpath='./img' data='<img src="image4_thumb.jpg">'>,
 <Selector xpath='./img' data='<img src="image5_thumb.jpg">'>]

打印结果的形式是 Selector 组成的列表,最后获得了 a 节点里面的所有 img 节点

选择器的最前方加 . ,代表提取元素内部的数据,如果没有加点,则代表从根节点开始提取。此处我们用了./img 的提取方式,则代表从 a 节点里进行提取。如果此处我们用 //img,则还是从 html 节点里进行提取。

提取具体内容:

>>> response.xpath('//a/text()').extract()
['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 'Name: My image 4 ', 'Name: My image 5 ']
>>> response.xpath('//a/@href').extract()
['image1.html', 'image2.html', 'image3.html', 'image4.html', 'image5.html']
>>> response.xpath('//a[@href="image1.html"]/text()').extract()
['Name: My image 1 ']

CSS选择器

上面提取所有 a 结点的过程用 CSS 选择器同样可以做到,如下所示:

>>> response.css('a')
[<Selector xpath='descendant-or-self::a' data='<a href="image1.html">Name: My image 1 <'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image2.html">Name: My image 2 <'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image3.html">Name: My image 3 <'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image4.html">Name: My image 4 <'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image5.html">Name: My image 5 <'>]

提取具体内容:

>>> response.css('a[href="image1.html"]').extract()
['<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>']
>>> response.css('a[href="image1.html"] img').extract()
['<img src="image1_thumb.jpg">']
>>> response.css('a[href="image1.html"] img').extract_first()
'<img src="image1_thumb.jpg">'

正则匹配

a 节点中的文本类似于 Name: My image 1,若只想把 Name: 后面的内容提取出来,就可以借助 re() 方法,实现如下:

>>> response.xpath('//a/text()').re('Name:\s(.*)')
['My image 1 ', 'My image 2 ', 'My image 3 ', 'My image 4 ', 'My image 5 ']

re() 方法传了一个正则表达式,其中 (.*) 就是要匹配的内容,输出的结果就是正则表达式匹配的分组,结果会依次输出

还有:

>>> response.xpath('//a/text()').re_first('(.*?):\s(.*)')
'Name'
>>> response.xpath('//a/text()').re_first('Name:\s(.*)')
'My image 1 '

猜你喜欢

转载自blog.csdn.net/weixin_44613063/article/details/103330756