一. 基本概念
Selector是一个可独立使用的模块,我们可以用Selector类来构建一个选择器对象,然后调用它的相关方法如xpaht(), css()等来提取数据,如下
from scrapy import Selector body= '<html><head><title>Hello World</title></head><body></body> </ html> ’ selector = Selector(text=body) title = selector.xpath('//title/text()').extract_first() print(title) 输出为 Hello World
scrapy shell 主要用于测试scrapy项目中命令是否生效,可在bash下直接执行,这里我们通过使用scrapy shell来验证学习选择器提取网页数据,在linux中bash下执行命令
scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html即可进入scrapy shell命令模式
上面测试网站源码
<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中有内置选择器response.selector,可用于提取网页信息
1. 比如抓取title的文本,两种方法
In [1]: response.selector.xpath('//title/text()').extract_first() Out[1]: 'Example website' In [2]: response.selector.css('title::text').extract_first() Out[2]: 'Example website'
注意:其中的selector可以不加
2. 抓取a标签中的内部文本和属性
In [6]: response.xpath('//a/text()').extract() Out[6]: ['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 'Name: My image 4 ', 'Name: My image 5 '] In [8]: response.xpath('//a/@href').extract() Out[8]: ['image1.html', 'image2.html', 'image3.html', 'image4.html', 'image5.html']
3. 如果符合要求的节点只有一个,我们用属性来限制的匹配的范围。比如查找id=images的所有div标签, 并且选中其中的img标签,,
注意[]中的id属性值image必须用双引号
In [3]: response.xpath('//div[@id="images"]').css('img') Out[3]: [<Selector xpath='descendant-or-self::img' data='<img src="image1_thumb.jpg">'>, <Selector xpath='descendant-or-self::img' data='<img src="image2_thumb.jpg">'>, <Selector xpath='descendant-or-self::img' data='<img src="image3_thumb.jpg">'>, <Selector xpath='descendant-or-self::img' data='<img src="image4_thumb.jpg">'>, <Selector xpath='descendant-or-self::img' data='<img src="image5_thumb.jpg">'>]
几个例子
1. 提取里面的数据,比如src地址
方法1:用xpath方法
#先选上src属性标签 response.xpath('//div[@id='images']').css('img::attr(src)')) #提取相应信息 response.xpath('//div[@id='images']').css('img::attr(src)')).extract() #得到多个 response.xpath('//div[@id='images']').css('img::attr(src)')).extract_first() #得到一个 response.xpath('//div[@id='images']').css('img::attr(src)')).extract_first(default='') #如果没提取到返回默认值 #获取a标签文本值 response.xpath('//a/text()').extract()
方法2:用css方法
response.css('a::attr(href)').extract() #提取属性
response.css('a::text').extract() #拿到a标签文本
例子2:查找属性名称包含image的所有a标签
response.xpath('//a[contains(@href, "image")]/@href').extract()
response.css('a[href*=image]::attr(href)'.extract()
例子3:查找img标签地址
response.xpath('//a[contains(@href, "image")]/img/@src').extract()
response.css('a[href*=image] img::attr(src)').extract()
例子4,结合正则表达式提取所需内容
response.css('a::text').re('Name\:(.*)') #提取(.*)代表的内容
response.css('a::text').re_first('Name\:(.*)').strip() #提取第一个(.*)代表的内容
注意:extract()方法把selector类型变为数据类型