BeautifulSoup对象

一、 三种方式创建 BeautifulSoup 对象

将文档传入 BeautifulSoup 构造方法即可生成文档对象,常见数据源有三种:

  1. 传入字符串(HTML/XML片段)
    直接解析一段字符串格式的网页代码。 from bs4 import BeautifulSoup soup = BeautifulSoup("<html>data</html>", "html.parser")
  2. 传入文件句柄(读取本地文件)
    打开本地 HTML 文件进行解析,建议指定编码格式(如 utf-8)避免乱码。 # 基础写法(图中示例未指定解析器,实际使用时建议补充如 "html.parser") soup = BeautifulSoup(open("index.html"), "html.parser") # 推荐写法:指定编码并使用 prettify() 格式化输出 soup = BeautifulSoup(open("index.html", encoding="utf-8"), "html.parser") print(soup.prettify())
  3. 通过 URL 获取 HTML 文档
    结合网络请求库(如 urllib)获取网页源码后再解析。 from bs4 import BeautifulSoup import urllib.request def gethtml(url): page = urllib.request.urlopen(url) html = page.read().decode("utf-8") return html html_doc = gethtml("http://www.cnblogs.com") soup = BeautifulSoup(html_doc, "html.parser") print(soup.prettify())

二、 对象的种类

BeautifulSoup 将复杂的 HTML 文档转换为树形结构,每个节点都是 Python 对象,主要归纳为 4 种类型:

  • Tag:原生文档中的标签(如 <b>、<p>)。
  • NavigableString:标签内部的文本内容。
  • BeautifulSoup:整个文档的根对象。
  • Comment:文档中的注释内容。

Tag 对象基础操作:

  • 获取 Tag:通过 soup.标签名 获取第一个匹配的标签。 soup = BeautifulSoup('<b class="boldest">中间内容</b>', "html.parser") tag = soup.b print(type(tag)) # 输出: <class 'bs4.element.Tag'>
  • Name(标签名):通过 .name 获取标签名称。 print(tag.name) # 输出: b
  • Attributes(属性操作):属性操作方式与字典完全相同,支持获取、添加、修改、删除。 # 获取属性(多种方式) print(tag['class']) # 输出: ['boldest'] (或 'boldest' 视版本而定) print(tag.get('class')) # 修改/添加属性 tag['class'] = 'verybold' tag['id'] = 1

三、 多值属性

  • HTML 中部分属性可包含多个值(最常见的是 class,还有 rel、rev、accept-charset 等)。
  • 在 BeautifulSoup 中,多值属性被解析后返回的类型是列表(list)。 # 例如 <b class="boldest verybold"> 中 # tag['class'] 的返回值为 ['boldest', 'verybold']

以下是关于 BeautifulSoup 处理多值属性(以 class 为例)在不同场景下的返回值差异及核心要点:

一、 HTML 格式下的多值属性

在 HTML 文档中,class 属性支持同时指定多个值(以空格分隔)。BeautifulSoup 会将其自动解析为列表(list)类型。

from bs4 import BeautifulSoup

# 包含多个 class 值
css_soup = BeautifulSoup('<p class="body strikeout"></p>', 'html.parser')
print(css_soup.p['class'])  
# 输出: ['body', 'strikeout'] (返回列表)

# 只包含单个 class 值
css_soup2 = BeautifulSoup('<p class="body"></p>', 'html.parser')
print(css_soup2.p['class'])  
# 输出: ['body'] (即使只有一个值,依然返回单元素列表)Code language: PHP (php)

二、 XML 格式下的属性处理

如果文档以 XML 解析器(xml)进行转换,XML 规范中不包含多值属性的概念。此时属性值会被视为完整的纯字符串,不做拆分。

from bs4 import BeautifulSoup

xml_soup = BeautifulSoup('<p class="body strikeout"></p>', 'xml')
print(xml_soup.p['class'])  
# 输出: 'body strikeout' (返回完整字符串,而非列表)Code language: PHP (php)

三、 核心差异对比

解析模式代码示例tag['class'] 返回类型返回值示例
HTML 模式​BeautifulSoup(html, 'html.parser')列表 (list)​['body', 'strikeout']
单值 class​class="body"列表 (list)​['body']
XML 模式​BeautifulSoup(xml, 'xml')字符串 (str)​'body strikeout'

四、 注意

  1. 默认解析器差异:图中代码未显式写出 HTML 解析器参数(如 html.parser),实际开发中建议始终补充,否则可能触发警告或依赖系统默认解析器(如 lxml)。
  2. 其他多值属性:除 class 外,HTML 中的 rel、rev、accept-charset 等在 HTML 模式下同样返回列表,在 XML 模式下返回字符串。
  3. 属性操作一致性:获取时类型有差异,但修改方式一致(如 tag['class'] = 'new_class' 或赋值为列表 tag['class'] = ['a', 'b']),BeautifulSoup 会在输出时根据解析器类型自动处理格式。

例子

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>

<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://foxdevelop.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://foxdevelop.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://foxdevelop.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
"""

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc)

print(soup.prettify())
print(soup.title)

for link in soup.find_all('a'):
    print(link.get('href'))

print(soup.get_text())

soup2 = BeautifulSoup(open("index.html", encoding="utf-8"))
print(soup2.prettify())Code language: HTML, XML (xml)

远程抓取

from bs4 import BeautifulSoup
import urllib.request


def gethtml(url):
    page = urllib.request.urlopen(url)
    html = page.read().decode("utf-8")
    return html


html_doc = gethtml("http://www.cnblogs.com")
soup = BeautifulSoup(html_doc)
print(soup.prettify())Code language: JavaScript (javascript)

属性 和对象

from bs4 import BeautifulSoup

soup = BeautifulSoup('<a></a><b class="boldest" sddsf="foxdevelop.com">中间内容</b>')
print(soup.b)
print(soup.a)
print(type(soup))
print(type(soup.b))
soup.b.name = "span"
print(soup)
# <span class="boldest">中间内容</span>
print(soup.span["class"][0])
# boldest
print(soup.span.get('sddsf'))
# foxdevelop.comCode language: PHP (php)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注