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选择器介绍

python中使用css_css


第一张里的表达式较为常用。

python中使用css_html_02


python中使用css_html_03

三、实操

1、前提

继续沿用在scrapy框架(2):入口文件中写的bokeyuanSpider和main入口文件

python中使用css_css_04


python中使用css_pycharm_05

2、code实现的方法介绍

①、Pycharm debug

②、黑窗口

首先,进入虚拟环境
workon envName

python中使用css_python中使用css_06

然后,shell
scrapy shell https://www.cnblogs.com/

执行完这一句后将会显示“>>>”即进入了python

python中使用css_css_07

3、数据提取

我们要爬取的是博客园首页的文章标题、作者昵称、文章网址、发布时间、点赞数、评论数以及浏览数。

(1)文章标题

python中使用css_css_08


首先观察标题的标签,标签的属性中有class,所以我们考虑用.

response.css(".post-item-title::text").extract()

我们将语句拆解开实行,以了解每一部分的具体作用

① .post-item-title
response.css(".post-item-title")

python中使用css_css_09


拿到的实际上是一个scrapy.selector.unified.SelectorList对象

python中使用css_python中使用css_10

② ::text的意思是取标签的内容
response.css(".post-item-title::text")

python中使用css_css_11


取到数据的类型也是一个对象

python中使用css_python_12

③ .extract()
response.css(".post-item-title::text").extract()

python中使用css_css_13


类型为list列表,这才是我们真正需要的数据

python中使用css_pycharm_14

(2)作者昵称

python中使用css_python中使用css_15


可以发现这其中既没有属性id也没有属性class,所以需要定位副标签

上一层标签里有class

python中使用css_python_16

所以使用.,空格表示下一层

response.css(".post-item-author span::text").extract()

python中使用css_css_17

(3)文章网址url

href是标签的属性

python中使用css_python中使用css_18

response.css(".post-item-title::attr(href)").extract()

::attr(属性名)

python中使用css_python_19

(4)发布时间

python中使用css_python_20


第一眼看上去和作者名称的形式一样,那我们试一试按照上面的格式提取

response.css(".post-meta-item span::text").extract()

python中使用css_python_21

python中使用css_css_22


由此看出这个数据存在噪声,回开发者工具看一下问题出在哪里。

借此说一下Chrome开发者工具如何查找匹配代码:Ctrl+F后,下方会出现一个搜索框:

python中使用css_python_23


会发现有两个并列的class=post-meta-item,所以code需要进一步改进。

发布时间所在的标签的span,而另一个是a标签,所以在.前加上标签的类型:

response.css("span.post-meta-item span::text").extract()

python中使用css_pycharm_24


为了更加了解这个操作,再单独提取一下噪声

python中使用css_html_25

(5) 点赞数、评论数以及浏览数

python中使用css_pycharm_26

观察代码可知点赞数、评论数以及浏览量的span标签都和svg标签属于并列关系,a标签包含span标签,所以提取时间时的噪声数据就是这一步需要提取的数据。

response.css("a.post-meta-item span::text").extract()

python中使用css_pycharm_27


单独提取出每一类数据的方法有两种

① 步长

点赞数即从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):入口文件

python中使用css_python_28

四、总结

标签属性里有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链接