Python爬虫实例(3)--BeautifulSoup的CSS选择器

Python爬虫实例

紧接着上一讲的内容。
我们初步了解了bs4这个解析库。

但是bs4难道只有find,find_all了吗?

如果层次比较深,相似的元素比较多,和可能会写的比较长。

最主要的是很难搞清逻辑。
所以这一章是bs4的中级部分。

任务:解析修真聊天群的章节标题。

网页数据见上一讲。

本期耗时15min。练习耗时15min。



前言

最开始的工具介绍里提到过BeautifulSoup,lxml包。

在速度上正则表达式和lxml是比较突出的。lxml是基于C语言的,而BeautifulSoup使用Python编写,因此BeautifulSoup在性能上略逊一筹也不奇怪。但BeautifulSoup使用起来更方便一些,且支持CSS选择器,这也能够弥补其性能上的不足。另外最新版的bs4也已经支持lxml作为解析器。使用lxml时程序主要根据XPath来解析,如果熟悉XPath的语法,那么lxml和BeautifulSoup都是很好的选择。

一、select选择器

通过上一节,我们看到find的用法。我相信各位因该有感触。

  1. 笼统。find是对所有的子孙查找。目标太大,及时加了限定也很飘。
  2. 局限。返回的要么是一个,要么可能太多。
  3. 步长短。为了精确可能需要一步步逼近。然后写的老长。可能还要分类讨论。。。

select函数简介

select代表的就是选择器。返回值是一个列表。
status = soup.select('#contentcolumn > div > span:nth-child(4)')

我们提到过一次选择器,就是CSS那一篇文章。
css选择器
select支持CSS语法,其实本来就是受到了CSS的启发。

CSS语法选择器

基本和CSS选择器语法一致。

content = soup.find("div",attrs={"id":"book"}).find("div",attrs={"id":"info"}).find('p').string
content1 = soup.select('div#book div#info p:nth-child(2)')[0].string
print(content)
print(content1)
作    者:圣骑士的传说
作    者:圣骑士的传说

我们可以看到效果一致,并且更加的精简了。

注意:

  1. 空格代表递进关系
  2. [0],select返回值是一个列表所以不能直接string。不是解析字符串。
  3. nth-child(2)代表第二个节点。:nth-child() 选择器,该选择器选取父元素的第 N 个子元素,与类型无关。
    所以这里即使是第一个p,但是却是2。

当然也可以选中全部的p出来用列表索引,如下:

content2 = soup.select('div#book div#info p')[0].string

效果是一样的。

二、实操

目标的确认

观察内容,返现基本是一个列表,但是有一些妨碍的序言部分,需要去除。

		<dd><a href ="/1_1852/526426166.html">3167章 哥哥,我们家果然不是普通人对吧?</a></dd>
		<dd><a href ="/1_1852/529533214.html">3166章 我的妹妹,当你出生的那一天……</a></dd>
		<dd><a href ="/1_1852/530029322.html">3165章 霸妹变成了面瘫</a></dd>
		<dd><a href ="/1_1852/530224932.html">3164章 此女类我</a></dd>
		<dd><a href ="/1_1852/530584964.html">完本感言</a></dd>
		<dd><a href ="/1_1852/530590713.html">3163章 霸宋邀请你加入群‘九洲一号群’【大结局】</a></dd>
		<dd><a href ="/1_1852/530693596.html">今天先一章……明天大结局</a></dd>
		<dt>《修真聊天群》正文卷</dt>
		<dd><a href ="/1_1852/835564.html">第一章 黄山真君和九洲一号群</a></dd>
		<dd><a href ="/1_1852/835565.html">第二章 且待本尊算上一卦</a></dd>
		<dd><a href ="/1_1852/835566.html">第三章 一张丹方</a></dd>
		<dd><a href ="/1_1852/835567.html">第四章 H市三品后天雷劫</a><

方案选择

直接定位dd标签行不行?

不行,列表一个页面可能有很多,干扰元素太多。

定位

<div class="listmain">

行不行,可以,而且距离目标关系不是很远。

干扰信息的排除

我们发现dt标签没有a标签是分割信息。
在两次dt之后才是我们要的dd内容。

raw_titles = soup.select('div.listmain dl dd,dt')
# print(raw_titles)

dt_nu = 0 # flag
filter_list = []
for title in raw_titles:

    if not title.find('a') :
        print("dt")
        dt_nu +=1
    
    if dt_nu >=2 and title.find('a') :
        title_str = title.find('a').string
        filter_list.append(title_str)

print(dt_nu)
print(filter_list)
with open("sector.txt","w",encoding='utf-8') as SEC:
    for title in filter_list:
        if title:# 过滤空值
            SEC.write(title+"\n")

在这里插入图片描述

结果自然是很完美啦!!!

select返回的基础的类型是和find,find_all一致的。所以两种方法可以相互嵌套。


总结

这一章,我们讲解了更为简单的定位工具。
CSS选择器select。更多的参数需要具体查看使用说明。
并且在不同的实例下联系。

在实战中很少用到find,所以忘记也无所谓。。。可能也就如上的if里面用的到。

下一讲我们介绍另一个规则工具,xpath。

虽然形式上相差比较多,但是定位用的锚点无非就那么几个。

标签,id,属性,类。

需要的是,灵活的运用。

一键三连吧,朋友们。。。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

演技拉满的白马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值