Python爬虫:想听榜单歌曲?使用BeautifulSoup库只需要14行代码即可搞定

article/2025/9/10 13:35:09

目录

  • BeautifulSoup库
    • 安装BeautifulSoup库
    • BeautifulSoup库简介
    • 选择解释器
      • 基础用法
    • 节点选择器
      • 获取节点名称属性内容
      • 获取所有子节点
      • 获取所有子孙节点
      • 父节点与兄弟节点
    • 方法选择器
      • find_all()方法
      • find()方法
    • CSS选择器
      • 嵌套选择节点
      • 获取属性与文本
    • 通过浏览器直接Copy-CSS选择器
    • 实战:抓取酷狗飙升榜榜单

BeautifulSoup库

虽然说XPath比正则表达式用起来方便,但是没有最方便,只有更方便。我们的BeautifulSoup库就能做到更方便的爬取想要的东西。

安装BeautifulSoup库

使用之前,还是老规矩,先安装BeautifulSoup库,指令如下:

pip install beautifulsoup4

其中文开发文档:

https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

BeautifulSoup库简介

BeautifulSoup库是一个强大的Python语言的XML和HTML解析库。它提供了一些简单的函数来处理导航、搜索、修改分析树等功能。

BeautifulSoup库还能自动将输入的文档转换为Unicode编码,输出文档转换为UTF-8编码。

所以,在使用BeautifulSoup库的过程中,不需要开发中考虑编码的问题,除非你解析的文档,本身就没有指定编码方式,这才需要开发中进行编码处理。

下面,我们来详细介绍BeautifulSoup库的使用规则。

选择解释器

下面,我们来详细介绍BeautifulSoup库的重点知识。

首先,BeautifulSoup库中一个重要的概念就是选择解释器。因为其底层依赖的全是这些解释器,我们有必要认识一下。博主专门列出了一个表格:

解释器使用方式优点缺点
Python标准库BeautifulSoup(code,‘html.parser’)Python的内置标准库,执行速度适中,容错能力强Python2.7.3以及Python3.2.2之前的版本容错能力差
lxml HTML解析器BeautifulSoup(code,‘lxml’)解析速度快,容错能力强需要安装C语言库
lxml XML解析器BeautifulSoup(code,‘xml’)解析速度快,唯一支持XML的解析器需要安装C语言库
html5libBeautifulSoup(code,‘html5lib’)最好的容错性,以浏览器的方式解析文档,生成HTML5格式的文档解析速度慢

从上面表格观察,我们一般爬虫使用lxml HTML解析器即可,不仅速度快,而且兼容性强大,只是需要安装C语言库这一个缺点(不能叫缺点,应该叫麻烦)。

基础用法

要使用BeautifulSoup库,需要和其他库一样进行导入,但你虽然安装的是beautifulsoup4,但导入的名称并不是beautifulsoup4,而是bs4。用法如下:

from bs4 import BeautifulSoupsoup = BeautifulSoup('<h1>Hello World</h1>', 'lxml')
print(soup.h1.string)

运行之后,输出文本如下:

基础用法

节点选择器

基础的用法很简单,这里不在赘述。从现在开始,我们来详细学习BeautifulSoup库的所有重要知识点,第一个就是节点选择器。

所谓节点选择器,就是直接通过节点的名称选择节点,然后再用string属性就可以得到节点内的文本,这种方式获取最快。

比如,基础用法中,我们使用h1直接获取了h1节点,然后通过h1.string即可得到它的文本。但这种用法有一个明显的缺点,就是层次复杂不适合。

所以,我们在使用节点选择器之前,需要将文档缩小。比如一个文档很多很大,但我们获取的内容只在id为blog的div中,那么我们先获取这个div,再在div内部使用节点选择器就非常合适了。

HTML示例代码:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>我是一个测试页面</title>
</head>
<body>
<ul class="ul"><li class="li1"><a href="https://liyuanjinglyj.blog.csdn.net/">我的主页</a></li><li class="li2"><a href="https://www.csdn.net/">CSDN首页</a></li><li class="li3"><a href="https://www.csdn.net/nav/python" class="aaa">Python板块</a></li>
</ul>
</body>
</html>

下面的一些示例,我们还是使用这个HTML代码进行节点选择器的讲解。

获取节点名称属性内容

这里,我们先来教会大家如何获取节点的名称属性以及内容,示例如下:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html, 'lxml')
# 获取节点的名称
print(soup.title.name)
# 获取节点的属性
print(soup.meta.attrs)
print(soup.meta.attrs['charset'])
# 获取节点的内容(如果文档有多个相同属性,默认获取第一个)
print(soup.a.string)
# 也可以一层一层的套下去
print(soup.body.ul.li.a.string)

运行之后,效果如下:

属性与内容

这里的注释代码都很详细,就不在赘述。

获取所有子节点

一般来说一个节点的子节点有可能很多,通过上面的方式获取,只能得到第一个。如果要获取一个标签的所有子节点,这里有2种方式。先来看代码:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html, 'lxml')
# 获取直接子节点
print("获取直接子节点")
contents = soup.head.contents
print(contents)
for content in contents:print(content)
children = soup.head.children
print(children)
for child in children:print(child)

运行之后,效果如下:

所有子节点
如上面代码所示,我们有2种方式获取所有子节点,一种是通过contents属性,一种是通过children属性,2者遍历的结果都是一样的。

但需要特别注意,这里获取所有子节点,它是把换行符一起算进去了,所以你会看到控制台输出了很多空行。所以,在实际的爬虫中,遍历之时一定要删除这些空行。

获取所有子孙节点

既然能获取直接子节点,那么获取所有子孙节点也是肯定可以的。BeautifulSoup库给我们提供了descendants属性获取子孙节点,示例如下:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html, 'lxml')
# 获取ul的所有子孙节点
print('获取ul的所有子孙节点')
lis = soup.body.ul.descendants
print(lis)
for li in lis:print(li)

运行之后,效果如下:

所有子孙节点

同样的,descendants获取子孙节点也算入了换行符。而且需要特别注意的是,descendants属性把文本内容本身也算作子孙节点。

父节点与兄弟节点

同样的,在实际的爬虫程序中,我们有时候也需要通过逆向查找父节点,或者查找兄弟节点。

BeautifulSoup库,给我们提供了parent属性获取父节点,同时提供了next_sibling属性获取当前节点的下一个兄弟节点,previous_sibling属性获取上一个兄弟节点。

示例代码如下:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html, 'lxml')
# 获取第一个a标签的父亲节点的class属性
print(soup.a.parent['class'])
li1 = soup.li
li3 = li1.next_sibling.next_sibling.next_sibling.next_sibling
li2 = li3.previous_sibling.previous_sibling
print(li1)
print(li2)
print(li3)
for sibling in li3.previous_siblings:print(sibling)

运行之后,效果如下:

兄弟父亲节点

前面已经提示了,节点选择器是把换行符‘\n’也算一个节点,所以第一个li需要通过两个next_sibling才能获取到下一个li节点。同样的,上一个也是。其实还有一个更简单的方法,能避免这些换行符被统计在内,那就是在获取网页源代码的时候,直接去掉换行与空格即可。

方法选择器

对于节点选择器,博主已经介绍了相对于文本内容较少的完全可以这么做。但实际的爬虫爬的网址都是大量的数据,开始使用节点选择器就不合适了。所以,我们要考虑通过方法选择器进行先一步的处理。

find_all()方法

find_all()方法主要用于根据节点的名称、属性、文本内容等选择所有符合要求的节点。其完整的定义如下所示:

def find_all(self, name=None, attrs={}, recursive=True, text=None,limit=None, **kwargs):
参数意义
name指定节点名称
attrs指定属性名称与值,比如查找value="text"的节点,attrs={“value”:“text”}
recursive布尔类型,值True查找子孙节点,值False直接子节点,默认为True
text指定需要查找的文本
limit因为find_all返回的是一个列表,所以可长可短,而limit与数据库语法类似,限制获取的数量。不设置返回所有

【实战】还是测试上面的HTML,我们获取name=a,attr={“class”:“aaa”},并且文本等于text="Python板块"板块的节点。

示例代码如下所示:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html.strip(), 'lxml')
a_list = soup.find_all(name='a', attrs={"class": 'aaa'}, text='Python板块')
for a in a_list:print(a)

运行之后,效果如下所示:

find_all

find()方法

find()与find_all()仅差一个all,但结果却有2点不同:

  1. find()只查找符合条件的第一个节点,而find_all()是查找符合条件的所有节点
  2. find()方法返回的是bs4.element.Tag对象,而find_all()返回的是bs4.element.ResultSet对象

下面,我们来查找上面HTML中的a标签,看看返回结果有何不同,示例如下:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html.strip(), 'lxml')
a_list = soup.find_all(name='a')
print("find_all()方法")
for a in a_list:print(a)
print("find()方法")
a = soup.find(name='a')
print(a)

运行之后,效果如下:

效果

CSS选择器

首先,我们来了解一下CSS选择器的规则:

  1. .classname:选取样式名为classname的节点,也就是class属性值是classname的节点
  2. #idname:选取id属性为idname的节点
  3. nodename:选取节点名为nodename的节点

一般来说,在BeautifulSoup库中,我们使用函数select()进行CSS选择器的操作。示例如下:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html.strip(), 'lxml')
li = soup.select('.li1')
print(li)

这里,我们选择class等于li1的节点。运行之后,效果如下:

CSS选择器的基本用法

嵌套选择节点

因为,我们需要实现嵌套CSS选择器的用法,但上面的HTML不合适。这里,我们略作修改,仅仅更改<ul>标签内的代码。

<ul class="ul"><li class="li"><a href="https://liyuanjinglyj.blog.csdn.net/">我的主页</a></li><li class="li"><a href="https://www.csdn.net/">CSDN首页</a></li><li class="li"><a href="https://www.csdn.net/nav/python" class="aaa">Python板块</a>
</ul>

我们仅仅删除了li后面的数字,现在我们可以实现一个嵌套选择节点的效果了。示例代码如下所示:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html.strip(), 'lxml')
ul = soup.select('.ul')
for tag in ul:a_list = tag.select('a')for a in a_list:print(a)

运行之后,效果如下:

示例代码

获取属性与文本

我们再次将上面的代码改造一下,因为上面获取的标签,现在我们来获取其中的文本以及href属性的值,示例如下:

from bs4 import BeautifulSoupwith open('demo.html', 'r', encoding='utf-8') as f:html = f.read()
soup = BeautifulSoup(html.strip(), 'lxml')
ul = soup.select('.ul')
for tag in ul:a_list = tag.select('a')for a in a_list:print(a['href'], a.get_text())

运行之后,效果如下:

属性与值

可以看到,我们通过[‘属性名’]进行属性值的获取,通过get_text()获取文本。

通过浏览器直接Copy-CSS选择器

与XPath类似,我们可以直接通过F12浏览器进行Copy任何节点的CSS选择器代码。具体操作如下图所示:

Copy selector
在这里插入图片描述
copy之后,直接将上面复制的内容粘贴到select()方法中即可使用。

实战:抓取酷狗飙升榜榜单

上面基本上是BeautifulSoup库的全部用法,既然我们已经学习掌握了,不抓紧爬点什么,总感觉自己很亏,所以我们选择酷狗飙升榜榜单进行爬取。

酷狗飙升榜代码
如上图所示,我们的榜单信息全在id="rankWrap"的div标签下的ul之中。所以,首先我们必须获取ul。示例代码如下:

from bs4 import BeautifulSoup
import requestsurl = "https://www.kugou.com/yy/html/rank.html"
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
result = requests.get(url=url, headers=headers)
print(result.text)
soup = BeautifulSoup(result.text.strip(), 'lxml')
ul = soup.select('#rankWrap > div.pc_temp_songlist.pc_rank_songlist_short > ul')
print(tbody)

获取ul之后,我们就可以在获取其中的所有li节点信息,然后分解li的标签,获取重要的歌曲作者,歌曲名称等。不过,我们先来分析网页li内部代码:

li代码
可以看到,我们要的歌曲名称与作者就在li的title属性中,而歌曲的网页链接在li下,第4个span的标签下的a节点的href属性之中(也可以直接就是第一个a标签之中)。知道这些之后,我们可以完善代码了。

from bs4 import BeautifulSoup
import requestsurl = "https://www.kugou.com/yy/html/rank.html"
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
result = requests.get(url=url, headers=headers)
soup = BeautifulSoup(result.text.strip(), 'lxml')
ul = soup.select('#rankWrap > div.pc_temp_songlist.pc_rank_songlist_short > ul')
lis = ul[0].select('li')
for li in lis:print("歌曲名称与歌曲作者:", li['title'])print("歌曲链接:", li.find('a')['href'])

如上面代码所示,我们只用了不到14行代码,就可以爬取酷狗音乐的飙升榜单,BeautifulSoup库是不是非常的强大呢?

最终效果


http://chatgpt.dhexx.cn/article/u2aibu19.shtml

相关文章

【java毕业设计】基于B/S结构+mysql的KTV点歌系统设计与实现(程序源码)-KTV点歌系统

基于B/S结构mysql的KTV点歌系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于B/S结构mysql的KTV点歌系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及论文的获取方式。更多毕业设…

Django实现音乐网站 ⑽

使用Python Django框架制作一个音乐网站&#xff0c; 本篇主要是后台对歌曲类型、歌单功能原有功能进行部分功能实现和显示优化。 目录 歌曲类型功能优化 新增编辑 优化输入项标题显示 父类型显示改为下拉菜单 列表显示 父类型显示名称 过滤器增加父类型 歌单表功能优化…

原始音频数据合成音频文件_根据音频数据对歌曲类型进行分类

原始音频数据合成音频文件 Over the past few years, streaming services have become the primary means through which most people listen to their favourite music. However, this can mean that users might find it difficult to look for newer music that suits their…

vue实现多页面应用

近期做的vue项目中&#xff0c;需要新增一个系统帮助页面&#xff0c;并且要在新的窗口中打开&#xff0c;但是vue是单页面应用&#xff0c;所以只能对项目进行改造&#xff0c;变成多页面项目。 第一步:在和index.html页面同级下新增一个helpinfo.html,在src目录下新增一个js目…

创建Vue单页面应用的3种方法

创建Vue单页面应用的3种方法 首先下载Vue CLI1.命令行创建&#xff08;推荐&#xff09;2.Vue ui&#xff08;不推荐&#xff09;3.Vite&#xff08;未来流行&#xff0c;现在还不稳定&#xff09; 首先下载Vue CLI 官方链接&#xff1a;https://cli.vuejs.org/zh/guide/insta…

单页和多页应用(vue.js学习笔记)

1.什么是单页面和多页面&#xff1f; 单页&#xff1a; 单页应用将所有内容放在一个页面中&#xff0c;从而使整个页面更加流畅就用户体验而言&#xff0c;单机导航可以定位锚点&#xff0c;快速定位相应的部分&#xff0c;并轻松上下滚动。单页面应用提供的信息和一些主要内容…

Vue-router: 实现纯前端多页面应用(Vuecli+Element UI)

1.简介 1.1 为什么要用Vue-router 我想做一个带导航栏的简单web页面&#xff0c;页面的内容可以随导航栏的点击切换。第一个想法是想用webpack打包出几个页面&#xff0c;然后在每个页面的按钮上添加链接&#xff0c;但是这样做每次页面都要刷新&#xff0c;效率上存在很大问…

vue3+vite配置多页应用

下面是工程的目录结构&#xff0c;里面包含一个index.html作为图表页的应用访问入口&#xff0c;login.html页作为登录页的应用访问入口。 对应的vite.config.js的配置&#xff0c;主要是配置root、base、build这几个属性&#xff0c;具体说明参考下方注释&#xff1a; import …

51、Vue 单页面应用

目录 1、概念 2、单页面应用和多页面应用的区别 3、SPA 单页面的优缺点分别是什么&#xff1f; 1、概念 SPA单页面应用&#xff08;SinglePage Web Application&#xff09;&#xff0c;指只有一个主页面的应用&#xff0c;一开始只需要加载一次js、css等相关资源。所有内容…

vue多页面入口配置

*index.html(主页\项目入口&#xff09;,app.vue(根组件)&#xff0c;main.js(文件入口的配置) 1.进行项目入口的配置 在public下面&#xff0c;复制index.html修改文件名&#xff08;里面内容可以不变&#xff09; <!DOCTYPE html> <html lang""><…

vue多页面开发

为什么使用多页面开发 vue是单页面应用&#xff0c;对多页面的页面间的相互跳转间没有过渡效果&#xff0c;难以维护&#xff1b;当一个应用越来越大的时候单页面模式应付不来&#xff0c;这时候就需要使用多页面应用了。 多页和单页应用模式的对比 转载于&#xff1a;https:…

Vue3多页面开发

Vue3多页面开发 在Vue3中&#xff0c;多页面开发的配置比较简单&#xff0c;下面来看一下具体的操作步骤&#xff1a; 1.使用vue创建单页面应用程序 见《Vue3脚手架指南》文章 2.在项目的根目录下创建vue.config.js文件&#xff0c;如果已经创建则忽略 3.在src目录下新建mo…

nginx部署多个vue多页面项目

众所周知&#xff0c;vue主要是用于开发单页应用的&#xff0c;在网上&#xff0c;也可以通过修改配置文件&#xff0c;实现多页面应用的开发&#xff0c;通过配置方式的开发多页面会有较多的缺点&#xff0c;在网上有许多论述&#xff0c;在此不再多言。此篇文章主要讲的是vue…

vue多页实践-开发

环境 node v12.5.0系统 winvuecli vue/cli 4.5.15ide WebStorm 2021.1 x64 本文是将vue-cli创建的spa应用改造为多页应用。 我们可以把多页应用理解为由多个单页构成的应用&#xff0c;而何谓多个单页呢&#xff1f;其实你可以把一个单页看成是一个 html 文件&#xff0c;那么…

vue3搭建多页面应用的方法

生成vue3的项目 vue create pagesdemo 2.在src文件中添加pages文件夹&#xff0c;同时删除app.vue main.js 在pages下添加项目文件夹&#xff0c;里面的目录结构和 原src一致。如下图 3. 配置vue.config.js vue-cli提供了pags参数&#xff0c;可以使用这个参数进行多页面配置…

vue实现多页面应用开发,包含项目之间跳转

需求&#xff1a;在一个vue项目工程下&#xff0c;需要部署两个项目甚至多个项目。 实现思路&#xff1a; 第一步&#xff1a;在vue.config.js文件中配置两个项目的入口 module.exports {pages: {// index页面是必须的&#xff0c;作为主项目的入口页面index: {entry: ./sr…

vue3配置多页面

先说下项目需求&#xff0c;地址栏中更换&#xff0c;不同地址进入页面不同&#xff0c;类似路由&#xff0c;以下为两个地址 简而言之&#xff0c;就是在不配置路由的情况下&#xff0c;输入admin和membe会进入管理端页面和会员端页面&#xff0c; 分析需求之后可以使用vue配…

构建多页vue应用

目录 1. 初始化2. 编写页面内容3. 配置多页入口总结 一般来说&#xff0c;vue推荐构建单页应用&#xff0c;页面内容的切换是通过路由控制组件的替换来实现的。单页应用使得页面跳转变得极为迅速&#xff0c;不过假如两个页面在功能逻辑上是完全独立的&#xff0c;甚至可能需要…

vue配置多页面应用

第一步&#xff1a;使用vue-cli搭建项目&#xff08;注&#xff1a;建议安装淘宝镜像&#xff0c;使用cnpm执行下面操作&#xff09; 1.按住shift按钮&#xff0c;右键点击存放项目的文件夹&#xff0c;点击在此处打开命令窗口。 2.在命令窗口中输入 npm install -g vue-cli …