简介:本文围绕 Python 的 BeautifulSoup 库展开,介绍了其安装方式,详细解析了各类解析器(如标准库、lxml 库、xml 库、html5lib 等)的特点与作用,并通过代码案例展示不同解析器在实际应用中的表现。同时,还阐述了解析器的常用方法以及 BeautifulSoup 提取数据的常用方法,最后以爬取淘宝网首页为例,一步步呈现利用该库进行网页数据爬取的完整流程,助力读者掌握 BeautifulSoup 在数据解析与爬取方面的运用。
Python BeautifulSoup 库全解析:从解析器到网页数据爬取实战
- BeautifulSoup解析数据
-
- 安装方式
- 解析器
- 解析器有哪些
- 解析器的常用方法
- beautifulsoup提取数据的常用方法
- beautifulsoup爬取淘宝网首页
-
- (第一步)导入requests库和beautifulsoup库
- (第二步)设置url
- (第三步)设置headers中的user-agent,模拟成浏览器访问
- [(第四步)使用requests.get获得并输出状态码 stauts_code,查看访问情况](#(第四步)使用requests.get获得并输出状态码 stauts_code,查看访问情况)
- (第五步)在淘宝网首页右键查看网页源代码,找到字符串编码,并设置encoding
- (第六步)创建bs解析器
- (第七步)获得a标签中的url,过滤None,只要完整的URL:
BeautifulSoup解析数据
是一个用于解析 HTML 和 XML 文档的 Python 库。它提供了简单又方便的函数来遍历、搜索和修改解析树,使得从网页中提取数据变得更加容易。
安装方式
pip install bs4
或者
conda install bs4
解析器
解析器的作用,什么是解析器
- 作用1:构建文档树结构,比如 一个HTML中,body标签下 有三个 div div下有ist,这种父子树形关系
- 作用2:获得标签的属性 比如通过筛选 a 标签 的class 为某些值,来获得需要的a标签
解析器有哪些
- 标准库(html.parser):内置库,速度始终,容错能力强
- lxml库(lxml):速度快 ,容错能力强
- xml库(html.xml):速度快,但是只支持xml
- html5(html5lib):容错能力最强可生成html5但是运行慢扩展差
通过下面这段代码案例去测试不同解析器的作用:
python
from bs4 import BeautifulSoup
html_doc = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BeautifulSoup 解析器测试</title>
</head>
<body>
<h1 id="title">欢迎来到测试页面</h1>
<p class="content">这是一段测试内容。</p>
<p class="content">这里还有一段测试内容,包含一些特殊字符 <>&</p>
<div>
<a href="https://www.example.com">示例链接</a>
</div>
<ul>
<li>项目 1</li>
<li>项目 2</li>
</ul>
<p>这是一个不规范的标签,缺少结束标签</p
</body>
</html>
'''
# 使用 html.parser 解析
soup_html_parser = BeautifulSoup(html_doc, 'html.parser')
print("使用 html.parser 解析:")
print("标题:", soup_html_parser.find('h1').text)
print("第一个段落内容:", soup_html_parser.find('p', class_='content').text)
print("链接:", soup_html_parser.find('a')['href'])
# 使用 lxml 的 HTML 解析器解析
soup_lxml_html = BeautifulSoup(html_doc, 'lxml')
print("\n使用 lxml 的 HTML 解析器解析:")
print("标题:", soup_lxml_html.find('h1').text)
print("第一个段落内容:", soup_lxml_html.find('p', class_='content').text)
print("链接:", soup_lxml_html.find('a')['href'])
# 使用 html5lib 解析
soup_html5lib = BeautifulSoup(html_doc, 'html5lib')
print("\n使用 html5lib 解析:")
print("标题:", soup_html5lib.find('h1').text)
print("第一个段落内容:", soup_html5lib.find('p', class_='content').text)
print("链接:", soup_html5lib.find('a')['href'])
# 尝试使用 lxml 的 XML 解析器(由于文档是 HTML,这里会报错)
try:
soup_lxml_xml = BeautifulSoup(html_doc, 'html.xml')
print("\n使用 html 的 XML 解析器解析:")
print("标题:", soup_lxml_xml.find('h1').text)
print("第一个段落内容:", soup_lxml_xml.find('p', class_='content').text)
print("链接:", soup_lxml_xml.find('a')['href'])
except Exception as e:
print("\n使用 html 的 XML 解析器解析出错:", e)
因为这个文档是lxml的格式下,所以在使用xml解析器会报错。
解析器的常用方法
大家直接看例子更为直观,直接上代码:
python
from bs4 import BeautifulSoup
html_doc = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BeautifulSoup 解析器测试</title>
</head>
<body>
<h1 id="title">欢迎来到测试页面</h1>
<p class="content bg" float = "left">这是一段测试内容。</p>
<p class="content">这里还有一段测试内容,包含一些特殊字符 <>&</p>
<h2><!--这是html中的注释语法--></h2>
<div>
<a href="https://www.example.com">示例链接</a>
</div>
<ul>
<li>项目 1</li>
<li>项目 2</li>
</ul>
<p>这是一个不规范的标签,缺少结束标签</p
</body>
</html>
'''
# 使用 lxml 的 HTML 解析器解析
soup_lxml_html = BeautifulSoup(html_doc, 'lxml')
print(f"获取文章标签需要:{soup_lxml_html.title}")
print(f"获取标签中的文本内容需要.text:{soup_lxml_html.title.text}")
print(f"获取标签中的文本内容也可以需要.string.:{soup_lxml_html.title.string}")
print(f"但是二者是有区别的,string可以获取注释中的内容,而text不能,他只能获得正式的内容")
print(f"比如h2标签中的注释只可以通过string:{soup_lxml_html.h2.string}")
print(f"比如h2标签中的注释不可以通过text:{soup_lxml_html.h2.text}")
print(f"获取文章标签所有属性列表需要attrs:{soup_lxml_html.p.attrs}")
print(f"获取某个标签的单个属性需要get:{soup_lxml_html.p.get('class')}")
print(f"获取某个标签的单个属性需要【】:{soup_lxml_html.p['class']}")
beautifulsoup提取数据的常用方法
- find(标签,属性):找到第一个满足要求的数据
- find_all(标签,属性);找到所有满足要求的数据
- select( css的ID 或者class 或者属性) :因为不知道大家是否有css的基础,这里我给大家详细解释一下 什么是 ID 就是制作网页的人通过自己定义的ID 赋予对应id的标签一个属性(属性里可能有字体 颜色 宽高 背景等等),这个属性不会被 class属性覆盖,因为他权重比较高,且ID不能重复用 。class也是属性,比如一个标签有多个属性,这些属性之间后者会覆盖前者(比如一个标签 里有 三个class 他们都设置了颜色,只会执行最后一个class的颜色)
理论学完了,我们直接上代码,一目了然:
python
from bs4 import BeautifulSoup
html_doc = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BeautifulSoup 解析器测试</title>
</head>
<body>
<h1 id="title">欢迎来到测试页面</h1>
<p class="content bg" float = "left">这是一段测试内容。</p>
<p class="content">这里还有一段测试内容,包含一些特殊字符 <>&</p>
<h2><!--这是html中的注释语法--></h2>
<div class = "qwer">
<a href="https://www.example.com">示例链接1</a>
</div>
<div class = "asdf">
<a href="https://www.example.com">示例链接2</a>
</div>
<ul>
<li id = "gb">项目 1</li>
<li>项目 2</li>
</ul>
<p>这是一个不规范的标签,缺少结束标签</p
</body>
</html>
'''
# 使用 lxml 的 HTML 解析器解析
soup_lxml_html = BeautifulSoup(html_doc, 'lxml')
print(f"find只可以找到第一个满足条件的{soup_lxml_html.find('p', class_='''content''')}")
print(f"findall可以找到所有满足条件的{soup_lxml_html.find_all('p',class_='''content''')}")
print(f"找cssid属性需要select #:{soup_lxml_html.select('#gb')}")
print(f"找cssclass属性需要select .:{soup_lxml_html.select('.content')}")
print(f"根据层级关系找需要>{soup_lxml_html.select('div>a')}")
print(f"层级关系也可以设置class{soup_lxml_html.select('div.asdf>a')}")
beautifulsoup爬取淘宝网首页
(第一步)导入requests库和beautifulsoup库
python
import requests
from bs4 import BeautifulSoup
(第二步)设置url
注意:为了大家少出错养成一个好习惯,所有的字符串都要用三引号
python
url = '''https://www.taobao.com/'''
(第三步)设置headers中的user-agent,模拟成浏览器访问
这个user-agent,可以通过打开开发者工具F12或者右键检查的方式,任意抓包中找到user-agent复制过来用键值对的字典形式存储:
python
headers = {'user-agent':'''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'''}
(第四步)使用requests.get获得并输出状态码 stauts_code,查看访问情况
python
import requests
from bs4 import BeautifulSoup
url = '''https://www.taobao.com/'''
headers = {'user-agent':'''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'''}
response = requests.get(url,headers = headers)
print(response.status_code)
(第五步)在淘宝网首页右键查看网页源代码,找到字符串编码,并设置encoding
python
response.encoding = '''utf-8'''
(第六步)创建bs解析器
python
bs = BeautifulSoup(response.text,'lxml')
(第七步)获得a标签中的url,过滤None,只要完整的URL:
python
import requests
from bs4 import BeautifulSoup
url = '''https://www.taobao.com/'''
headers = {'user-agent':'''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'''}
response = requests.get(url,headers = headers)
response.encoding = '''utf-8'''
bs = BeautifulSoup(response.text,'lxml')
a_list = bs.find_all("a")
for a in a_list:
url = a.get('href')
if url == None:
continue
if url.startswith("http") or url.startswith("https"):
print(url)