CSS选择器提取数据
- 一、HTML涉及内容补充:
- 二、css选择器介绍
- 三、实操
- 1、前提
- 2、code实现的方法介绍
- ①、Pycharm debug
- ②、黑窗口
- 首先,进入虚拟环境
- 然后,shell
- 3、数据提取
- (1)文章标题
- ① .post-item-title
- ② ::text的意思是取标签的内容
- ③ .extract()
- (2)作者昵称
- (3)文章网址url
- (4)发布时间
- (5) 点赞数、评论数以及浏览数
- 四、总结
一、HTML涉及内容补充:
1、HTML标签是由尖括号包围的关键词< html >
2、开始标签< title >与结束标签< /title >成对出现,称为双标签
3、也有单标签< img >
4、双标签的关系: 包含关系和并列关系
5、<标签的属性> <>标签的内容</>
二、css选择器介绍
第一张里的表达式较为常用。
三、实操
1、前提
继续沿用在scrapy框架(2):入口文件中写的bokeyuanSpider和main入口文件
2、code实现的方法介绍
①、Pycharm debug
②、黑窗口
首先,进入虚拟环境
workon envName
然后,shell
scrapy shell https://www.cnblogs.com/
执行完这一句后将会显示“>>>”即进入了python
3、数据提取
我们要爬取的是博客园首页的文章标题、作者昵称、文章网址、发布时间、点赞数、评论数以及浏览数。
(1)文章标题
首先观察标题的标签,标签的属性中有class,所以我们考虑用.
response.css(".post-item-title::text").extract()
我们将语句拆解开实行,以了解每一部分的具体作用
① .post-item-title
response.css(".post-item-title")
拿到的实际上是一个scrapy.selector.unified.SelectorList对象
② ::text的意思是取标签的内容
response.css(".post-item-title::text")
取到数据的类型也是一个对象
③ .extract()
response.css(".post-item-title::text").extract()
类型为list列表,这才是我们真正需要的数据
(2)作者昵称
可以发现这其中既没有属性id也没有属性class,所以需要定位副标签
上一层标签里有class
所以使用.,空格表示下一层
response.css(".post-item-author span::text").extract()
(3)文章网址url
href是标签的属性
response.css(".post-item-title::attr(href)").extract()
::attr(属性名)
(4)发布时间
第一眼看上去和作者名称的形式一样,那我们试一试按照上面的格式提取
response.css(".post-meta-item span::text").extract()
由此看出这个数据存在噪声,回开发者工具看一下问题出在哪里。
借此说一下Chrome开发者工具如何查找匹配代码:Ctrl+F后,下方会出现一个搜索框:
会发现有两个并列的class=post-meta-item,所以code需要进一步改进。
发布时间所在的标签的span,而另一个是a标签,所以在.前加上标签的类型:
response.css("span.post-meta-item span::text").extract()
为了更加了解这个操作,再单独提取一下噪声
(5) 点赞数、评论数以及浏览数
观察代码可知点赞数、评论数以及浏览量的span标签都和svg标签属于并列关系,a标签包含span标签,所以提取时间时的噪声数据就是这一步需要提取的数据。
response.css("a.post-meta-item span::text").extract()
单独提取出每一类数据的方法有两种
① 步长
点赞数即从0开始,步长为2;评论数从1开始,步长为2;浏览量从2开始步长,为2。
② 余数
三个值为一篇文章的一组数据,所以列表索引除以3,余数为0的是点赞数,余数为1的是评论数,余数为2的是浏览量。
article_nums=response.css("a.post-meta-item span::text").extract()
thumbsup=[] # 点赞
comments=[] # 评论
views=[] # 浏览量
for i in range(len(article_nums)):
if(i%3==0):
thumbsup.append(article_nums[i])
if(i%3==1):
comments.append(article_nums[i])
if(i%3==2):
views.append(article_nums[i])
在pycharm中调试: (注意:调试的是入口文件main.py,具体可看scrapy框架(2):入口文件)
四、总结
标签属性里有class,提取的是标签的内容(::text和.extract())
response.css(".post-item-title::text").extract()
标签属性里有class,提取的是下一层标签span的内容(空格)
response.css(".post-item-author span::text").extract()
标签属性里有class,提取的是标签属性的内容(::attr())
response.css(".post-item-title::attr(href)").extract()
标签属性里有class,提取的是下一层标签span的内容,但是与span标签并列的标签的属性里也有相同的class属性,则需要增加span标签的名称
response.css("span.post-meta-item span::text").extract()
上述代码链接:Git链接