乐之之

知而行乐,乐而行之,天道酬勤,学无止境。
scrapy爬虫框架(二)scrapy中Selector的使用

  在scrapy框架前,相信大家或多或少的已经了解了一些网页数据解析方法,如:xpath、bs4、正则表达式等,但是在scrapy框架中也有一个内置的数据提取方法--Selector。在这里我们就先简单介绍一下Selector在scrapy中的运用及常用方法。

  为了方便示例,我们以官方文档中的示例页面源码进行演示,页面源码如下:

<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='image1.htm2'>Name: My image 2 <br/><img src='image2_thumb.jpg'/></a>
<a href='image1.htm3'>Name: My image 3 <br/><img src='image3_thumb.jpg'/></a>
<a href='image1.htm4'>Name: My image 4 <br/><img src='image4_thumb.jpg'/></a>
<a href='image1.htm5'>Name: My image 5 <br/><img src='image5_thumb.jpg'/></a>
</div>
</body>
</html>

一、Selector

  selector选择器是属于scrapy框架中的内置解析方法,同样属于parsel库来构建的。不过selector对parsel库进行了封装,结合scrapy使用。selector支持Xpath、CSS选择器和正则表达式。

1、scrapy外使用selector的方法

  • 先从scrapy库中导入Selector模块,再调用Selector中的xpath方法。
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)

  selector有extract()和extract_first()两个常用的方法。接下来我们看一下这两个方法的使用。

2、extract()

  在scrapy框架中通过selecrot提取得到的结果往往是以SelectorList的类型返回,所以其返回的值并不是真正的文本内容,具体内容需要用到extract()方法。

  selectorList类型如下:

[<Selector xpath='//a' data='<img src="image1_thumb.jpg">'>,
<Selector xpath='//a' data='<img src="image2_thumb.jpg">'>,
<Selector xpath='//a' data='<img src="image3_thumb.jpg">'>,
<Selector xpath='//a' data='<img src="image4_thumb.jpg">'>,
<Selector xpath='//a' data='<img src="image5_thumb.jpg">'>,]

  通过extract()可以取出以上数据所包含的具体内容。

  • title= response.selector.xpath('//img/@src').extract()
# 结果如下
['image1_thumb.jpg','image2_thumb.jpg','image3_thumb.jpg','image4_thumb.jpg','image5_thumb.jpg',]

 3、extract_first()

  • extract_first()则可以去除内容的第一个字符串。
  • title= response.selector.xpath('//img/@src').extract_first()
# 结果如下
'image1_thumb.jpg'

 4、添加所需要的参数

  若无内容,怕选取的内容没有,而导致报错,则可以在extract_first()中添加所需要显示的参数。如:

  • title= response.selector.xpath('//img/@href').extract_first(‘不详’)
# 结果如下
'不详'

 二、Xpath

  在scrapy中直接使用selector的方法:

  • title= response.selector.xpath('//title/text()').extract_first()

  由于scrapy中有一个属性selector,通过调用response.selector返回的内容,相当于response的text构造了一个selector对象,通过该对象,可以调用Xpath、CSS等解析方法,向方法内传入Xpath或CSS选择器参数就可以实现信息的提取。

  所以,在scrapy一般不会使用response.selector.xpath('//a')的方法,而是直接response.xpath('//a')。

# 运行结果
[<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 <'>,
]

  由于xpath在scrapy中的提取和解析的具体方法与xpath单独使用相同,所以在这就就不再多赘述其使用的具体方法。

三、CSS选择器

1、锁定标签

response.css('a')

2、获取标签文本和属性使用::text和::attr的写法。

  • ::text的写法示例
  • response.CSS('a[href="image1.html"]::text').extract_first()
    'Name: My image 1'
  • ::attr的写法示例
  • response.CSS('a[href="image1.html"] img::attr(src)').extract_first()
    'Name: My image 1'

3、嵌套使用解析方法

response.xpath('//a').CSS('img'].xpath('@src').extract()
['image1_thumb.jpg','image2_thumb.jpg','image3_thumb.jpg','image4_thumb.jpg','image5_thumb.jpg']

四、re

1、基础用法

  • scrapy框架中的selector选择器也支持正则表达式,如下:
  • response.xpath('//a/text()').re('Name:\s(.*)')
    ['My image 1','My image 2','My image 3','My image 4','My image 5']

2、多值提取

  • 如果存在两个分组,结果依然会按照排序输出,如下:
  • response.xpath('//a/text()').re('(.*?):\s(.*)')
    ['Name','My image 1','Name','My image 2','Name','My image 3','Name','My image 4','Name','My image 5']

3、re_first()

  • 类似extract_first(),re_first方法可以选取列表的第一个元素,用法如下:
  • response.xpath('//a/text()').re_first('(.*?):\s(.*)')
    'Name'
    response.xpath('//a/text()').re_first('Name:\s(.*)')
    'My image 1'

Ps:reponse对象不能直接调用re和re_first方法,若想全文进行正则匹配需要先调用xpath再进行正则匹配。

response.xpath('.').re_first('Name:\s(.*)<br>')
'My image 1'

posted on 2023-03-31 10:48  乐之之  阅读(321)  评论(0编辑  收藏  举报