【Python】爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法

bs4,全称BeautifulSoup 4 , 它是Python独有的一种解析方式。也就是说只有Python语言才可以通过这种方式去解析数据。

官网的介绍是这样的

看起来很复杂,我用自己的理解,通俗的解释一下

我们知道一个网页的源代码,是由多个标签组成,比如<html>、<div>、<td>、<span>等等组成的,而bs4就是用来帮我们精确定位标签位置,从而获取标签或者标签属性中内容的工具。bs4默认自带的解析器,但是官方推荐的是更强大 速度更快的 lxml解析器

【Python】爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法

一、bs4的安装

pip install bs4

pip install lxml

使用bs4解析时,推荐使用lxml解析器。这个在用xpath解析的时候也会用到

二、bs4解析原理

  • 首先实例化一个BeautifulSoup对象,并且将页面源代码加载到这个对象里
  • 调用BeautifulSoup对象中的相关属性或者方法进行标签定位和数据提取

1、如何实例化BeautifuSoup对象

a. 导入bs4包

from bs4 import BeautifulSoup

b.实例化对象

网页源代码,又分为本地已经持久化的HTML文件和网络上直接获取的源代码。

如果是本地已经持久化的文件,可以通过下面的方式将源代码加载到bs4对象中

fp = open('xxx.html', 'r', encoding='utf-8')

# lxml:解析器

soup = BeautifulSoup(fp, 'lxml')

如果是通过requests库获取的网页源代码,通过下面的方式进行加载

response = requests.get(url)

html = response.text

soup = BeautifulSoup(html, 'lxml')

c.数据解析的方法和属性

bs4能够将复杂的HTML转换成一个树形结构,每个节点都是Python对象。

soup.tagName(标签名): 返回的是文档中第一次出现tagName对应的标签及其相应内容

soup.tageName1.tageName2:返回tag1中tage2的标签及其内容

soup.find:等同于soup.tagName,返回第一个匹配到的对象

soup.find_all:返回所有的匹配到的对象。

参数解释:

  • name :要查找的标签名(字符串、正则、方法、True)
  • attrs: 标签的属性
  • recursive: 递归
  • text: 查找文本
  • **kwargs :其它 键值参数

    def find(self, name=None, attrs={}, recursive=True, text=None,

**kwargs):

"""Return only the first child of this Tag matching the given

criteria."""

r = None

l = self.find_all(name, attrs, recursive, text, 1, **kwargs)

if l:

r = l[0]

return r

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iXUox6yw-1611066850753)(C:UsersAdministratorAppDataRoamingTyporatypora-user-imagesimage-20210103164834540.png)]

上图是我从某网站截取的部分画面,翻译成HTML如下(只保留了对本次分析有用的部分,为了方便阅读删除了地址的域名信息)

<html>

<head><titel>测试Title</titel></head>

<body>

<div class="test">

<ul>

<li> <a href="https://segmentfault.com/a/1190000039030926/zhaosi.html">![](123456789.jpg)<p>尼古拉斯赵四</p></a> </li>

</ul>

</div>

<div class="nr_zt w1180">

<ul>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/zhengshuang.html">![](5940f2cd6b759.jpg)<p>郑爽</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/zhuyilong.html">![](5b56e0fabf5bf.jpg)<p>朱一龙</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/zhoudongyu.html">![](5a28b93be8155.jpg)<p>周冬雨</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/huyitian_1.html">![](5aa36dfbe5f61.jpg)<p>胡一天</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/yiyangqianxi.html">![](5a28d243b0382.jpg)<p>易烊千玺</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/dilireba.html">![](5a28b69334087.jpg)<p>迪丽热巴</p></a> </li>

</ul>

</div>

</body>

</html>

看下面几个例子

# 获取第一个li标签

# <li> <a href="http://www.win4000.com/mt/zhengshuang.html">![](http://pic1.win4000.com/tj/2017-06-14/5940f2cd6b759.jpg)<p>郑爽</p></a> </li>

print(soup.li)

# # 获取第一个li标签中a标签

# <a href="http://www.win4000.com/mt/zhengshuang.html">![](http://pic1.win4000.com/tj/2017-06-14/5940f2cd6b759.jpg)<p>郑爽</p></a>

print(soup.li.a)

#获取第一个li标签中a标签

print(soup.find('li').a)

# 获取所有li标签

print(soup.find_all('li'))

# 获取title标签

print(soup.title)

# 获取a标签的父级标签

print(soup.a.parent)

# 获取a标签的父级标签的名字

print(soup.a.parent.name)

如何获取HTML中的href?

在bs4中提取标签中的属性可以通过attrs来获取

from bs4 import BeautifulSoup

fp = open('baidu.html', 'r', encoding='utf-8')

soup = BeautifulSoup(fp, 'lxml')

# 如果获取一个可以这样写

result = soup.a.attrs['href']

# zhaosi.html

print(result)

# 获取全部,可通过先获取a标签 然后遍历获取

all_result = soup.find_all('a')

for i in all_result:

print(i.attrs['href'])

print("* " * 40)

# 如果我只想获取id = star的href,需要先对id进行筛选

# 返回所有包含id=star的a标签

star_result = soup.find_all('a', id='star')

for i in star_result:

print(i.attrs['href'])

# 返回包含id的标签(只要有id属性,并且有值的标签都返回)

soup.find_all(id=True)

# 假设尼古拉斯赵四 不是第一个a标签中的内容.提取对应的href

# 需要先定位class=‘test’对应div的位置

# 方法一:

result = soup.find('div', 'test')

print(result.a['href'])

# 方法二(class为python中关键字,因此查找html中的class属性需要添加个下划线 class_)

result1 = soup.find('div', class_='test')

print(result1.a['href'])

# 方法三

result2 = soup.find('div', attrs={'class': 'test'})

# 获取第一个a标签中的文本内容

print(soup.a.text)

a_result = soup.find_all('a')

for i in a_result:

# 生成的是一个迭代器

print(i.strings)

print(list(i.strings))

print(i.string)

print(i.text)

其他补充

# 返回子孙节点

# children返回迭代器

result = soup.a.children

for i in result:

print(i)

# 返回子孙节点, contents返回列表

r = soup.a.contents

print(r)

# 可以通过正则对某个属性进行匹配

# 比如返回href中以zh开头的标签

import re

reg = re.compile('^zh')

result = soup.find_all(href=reg)

print(result)

选择器

bs4非常强大,还支持css选择器。通过select来完成

<html>

<head><titel>测试Title</titel></head>

<body>

<div class="test">

<ul>

<li> <a href="https://segmentfault.com/a/1190000039030926/zhaosi.html">![](123456789.jpg)<p>尼古拉斯赵四</p></a> </li>

</ul>

</div>

<div class="nr_zt w1180">

<ul>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/zhengshuang.html">![](5940f2cd6b759.jpg)<p>郑爽</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/zhuyilong.html">![](5b56e0fabf5bf.jpg)<p>朱一龙</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/zhoudongyu.html">![](5a28b93be8155.jpg)<p>周冬雨</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/huyitian_1.html">![](5aa36dfbe5f61.jpg)<p>胡一天</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/yiyangqianxi.html">![](5a28d243b0382.jpg)<p>易烊千玺</p></a> </li>

<li> <a id="star" href="https://segmentfault.com/a/1190000039030926/dilireba.html">![](5a28b69334087.jpg)<p>迪丽热巴</p></a> </li>

</ul>

</div>

</body>

</html>

from bs4 import BeautifulSoup

fp = open('baidu.html', 'r', encoding='utf-8')

soup = BeautifulSoup(fp, 'lxml')

# 返回一个所有a标签的列表

result = soup.select('a')

# 返回第一个

result1 = soup.select('a')[0]

"""

class选择器 : .className

"""

# 一层一层的进行选择,用 > 连接 即 > : 表示一个层级

# 输出 class = nr_zt 下ul下的li下的a标签集合

a = soup.select('.nr_zt > ul > li > a')

# 多个层级关联,使用 空格。

# 输出 class= 'nr_zt' 下的a标签集合

b = soup.select('.nr_zt a')

"""

id选择器: # idName

"""

result = soup.select('#star')

# 通过href属性查找,返回列表

soup.select('a[href="https://segmentfault.com/a/1190000039030926/zhengshuang.html"]')

# 获取对应标签中img标签的src值

a = soup.select('a[href="https://segmentfault.com/a/1190000039030926/zhengshuang.html"]')[0]

print(a.img['src']) # 5940f2cd6b759.jpg

以上就是bs4的常用操作代码,实际上在具体的爬虫过程中,匹配的方式比较灵活,所以大家也不用可以的去背,只需要记住其原理即可。

【Python】爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法

以上是 【Python】爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法 的全部内容, 来源链接: utcz.com/a/103562.html

回到顶部