爬虫专栏第五篇:Python BeautifulSoup 库全解析:从解析器到网页数据爬取实战

简介:本文围绕 Python 的 BeautifulSoup 库展开,介绍了其安装方式,详细解析了各类解析器(如标准库、lxml 库、xml 库、html5lib 等)的特点与作用,并通过代码案例展示不同解析器在实际应用中的表现。同时,还阐述了解析器的常用方法以及 BeautifulSoup 提取数据的常用方法,最后以爬取淘宝网首页为例,一步步呈现利用该库进行网页数据爬取的完整流程,助力读者掌握 BeautifulSoup 在数据解析与爬取方面的运用。

Python BeautifulSoup 库全解析:从解析器到网页数据爬取实战

BeautifulSoup解析数据

是一个用于解析 HTML 和 XML 文档的 Python 库。它提供了简单又方便的函数来遍历、搜索和修改解析树,使得从网页中提取数据变得更加容易。

安装方式

pip install bs4

或者

conda install bs4

解析器

解析器的作用,什么是解析器

  1. 作用1:构建文档树结构,比如 一个HTML中,body标签下 有三个 div div下有ist,这种父子树形关系
  2. 作用2:获得标签的属性 比如通过筛选 a 标签 的class 为某些值,来获得需要的a标签

解析器有哪些

  1. 标准库(html.parser):内置库,速度始终,容错能力强
  2. lxml库(lxml):速度快 ,容错能力强
  3. xml库(html.xml):速度快,但是只支持xml
  4. 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">这里还有一段测试内容,包含一些特殊字符 &lt;&gt;&amp;</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">这里还有一段测试内容,包含一些特殊字符 &lt;&gt;&amp;</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提取数据的常用方法

  1. find(标签,属性):找到第一个满足要求的数据
  2. find_all(标签,属性);找到所有满足要求的数据
  3. 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">这里还有一段测试内容,包含一些特殊字符 &lt;&gt;&amp;</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)
相关推荐
Mr.看海9 分钟前
【深度学习量化交易9】miniQMT快速上手教程案例集——使用xtQuant获取基本面数据篇
人工智能·python·深度学习·量化交易·miniqmt
SchrodingerSDOG25 分钟前
(补)算法刷题Day19:BM55 没有重复项数字的全排列
数据结构·python·算法
Jacob_AI1 小时前
Prompt Engineering(吴恩达&OpenAI)
人工智能·python·prompt
runepic1 小时前
[python]使用 Pandas 处理 Excel 数据:分割与展开列操作
python·excel·pandas
Koi慢热2 小时前
蓝桥杯python赛道我来了
网络·python·网络协议·安全·web安全
测试19983 小时前
树控件、下拉框、文本框常用测试用例
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
传说中胖子3 小时前
windows下pyenv与宝塔python冲突解决
python·pyenv
codists3 小时前
《Django 5 By Example》阅读笔记:p551-p560
python·django·编程人
神仙别闹4 小时前
基于Python+Sqlite3实现的搜索和推荐系统
开发语言·python·sqlite
潜洋4 小时前
Pandas教程之二十九: 使用 Pandas 处理日期和时间
python·pandas