Loading... <div class="tip inlineBlock warning simple"> 🤖 本博客内容使用 GPT-4 技术进行润色 </div> `BeautifulSoup` 是一个用于从HTML或XML文件中提取数据的Python库。它创建了一个解析树,使用户能够方便地访问和修改页面内容。`BeautifulSoup` 提供了一些简单的、Python式的函数来导航、搜索和修改解析树。可以参考 [BeautifulSoup 官方文档](https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/) 进行学习。 ## 1. BeautifulSoup 基础入门 让我们以一个简单的 HTML 结构为起点: ```html <html> <body> <p class="title">标签树</p> </body> </html> ``` Beautiful Soup 是一个功能强大的库,专门用于解析、遍历和维护 HTML 或 XML 的“标签树”。 考虑以下简单的 `<p>` 标签: ```html <p class="title">标签树</p> ``` * `p`:元素名(Name),它们通常成对出现。 * `class="title"`:属性(Attributes),一个标签可以包含零个或多个属性。 * `<p>…</p>`:标签(Tag),是构成 HTML 文档的基础。 ### 基本元素详解 - **Tag(标签)**: 是构成 HTML 或 XML 文档的基本单位,以 `<` 开始,以 `>` 结束。 - **Name(标签名)**: 标签的名称,比如 `<p>` 标签的名字是 'p'。 - **Attributes(属性)**: 标签的属性,通常以键值对的形式存在,可以通过 `tag.attrs` 获取。 - **NavigableString(可导航字符串)**: 标签内非属性的字符串内容,可以通过 `tag.string` 获取。 - **Comment(注释)**: 特殊类型的 NavigableString,用于表示标签内的注释内容。 示例代码: ```python import requests from bs4 import BeautifulSoup html = requests.get("https://python123.io/ws/demo.html").text soup = BeautifulSoup(html, "html.parser") print("标签示例:") print(soup.title) print(soup.a) print("标签名示例:") print("a 标签的名称:", soup.a.name) print("a 标签父元素的名称:", soup.a.parent.name) print("属性示例:") print(soup.a.attrs) print("类属性:", soup.a.attrs["class"]) print("id 属性:", soup.a.attrs["id"]) print("非属性字符串示例:") print(soup.a.string) print(soup.p.string) print("注释部分示例:") print(type(soup.a.string)) print(type(soup.p.string)) ``` 这段代码演示了如何通过 BeautifulSoup 提取 HTML 标签的不同组成部分,并打印它们。 ## 2. 掌握 BeautifulSoup 的 HTML 遍历技巧 Beautiful Soup 库,也被称为 beautifulsoup4 或 bs4,通常以以下方式导入: ```python from bs4 import BeautifulSoup ``` ### HTML 内容遍历 Beautiful Soup 提供了多种遍历 HTML 内容的方法: #### 向下遍历 - `.contents`: 获取子节点的列表,包含了标签中的所有直接子节点。 - `.children`: 子节点的迭代器,用于遍历子节点,适合于循环访问每一个子节点。 - `.descendants`: 子孙节点的迭代器,可以遍历标签下的所有子孙节点,非常适合需要深层次遍历的场景。 #### 向上遍历 - `.parent`: 获取单个父节点,是访问节点的直接父节点的简便方法。 - `.parents`: 父节点的迭代器,可以遍历到从当前节点到根节点的所有父节点,适用于需要回溯的场景。 #### 横向遍历 - `.next_sibling`: 获取下一个兄弟节点,它可以让你访问同一层级的下一个节点。 - `.previous_sibling`: 获取上一个兄弟节点,与 `.next_sibling` 相反,它返回前一个节点。 - `.next_siblings`: 后续所有兄弟节点的迭代器,可以用来遍历一个节点之后的所有兄弟节点。 - `.previous_siblings`: 前面所有兄弟节点的迭代器,适用于需要向前遍历兄弟节点的情况。 `.prettify()` 方法可以使 HTML 输出更加易读: ```python html = requests.get("https://python123.io/ws/demo.html").text soup = BeautifulSoup(html, "html.parser") print(soup.prettify()) ``` 这将以格式化的方式输出整个 HTML 文档。 ## 3. 选择合适的解析器 Beautiful Soup 支持多种解析器,这些解析器有各自的优势: - **html.parser**: BeautifulSoup 的内置 HTML 解析器,不需要额外安装,适合基本的文档解析需求。 - **lxml**: 一个非常快速的 HTML 和 XML 解析器,需要通过 pip 安装。 - **html5lib**: 以浏览器的方式解析 HTML 文档的解析器,虽然速度较慢,但解析方式与浏览器极为相似。 安装不同的解析器很简单,只需使用 pip: ```bash pip install lxml pip install html5lib ``` ## 4. 信息标记和提取 ### 信息的标记 - **标记化的信息**:标记化后的信息可以构建成结构化的数据模型,增强了数据的可操作性和可理解性。 - **标记结构的重要性**:标记结构本身就像信息的骨架,对于信息的传递、存储及展示至关重要。 - **程序处理的便利性**:标记化的信息更容易被计算机程序所解析和利用。 #### 常见的信息标记形式 - **XML**: 是最早的通用信息标记语言,具有很好的扩展性,但相对较为繁琐。 - **JSON**: 一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。 - **YAML**: 一种人性化的数据序列化标准,适合所有的编程语言。 ### 信息提取策略 在标记化的信息中提取关键内容,可以采用以下策略: #### 完整解析 - 使用专门的标记解析器,例如 BeautifulSoup,可以实现对信息的精确解析。 - 优点是解析结果准确,缺点是过程可能比较繁琐,速度相对较慢。 #### 直接搜索 - 利用文本搜索方法,可以快速地查找到关键信息,但可能会牺牲一些准确性。 #### 结合解析与搜索 - 结合使用解析器和搜索函数,可以在保证一定准确性的同时提高效率。 ## 5. 利用 BeautifulSoup 进行 HTML 内容查找 BeautifulSoup 提供了丰富的方法来查找 HTML 文档中的特定内容: ```python soup.find_all(name, attrs, recursive, string, **kwargs) ``` 参数详解: - `name`: 可以是一个标签名称或者一个标签名称的列表,用于查找所有匹配的标签。 - `attrs`: 是一个字典,用于搜索具有特定属性的标签。 - `recursive`: 布尔值。如果是 True(默认值),Beautiful Soup 会检查标签的所有子孙节点。如果是 False,只会检查标签的直接子节点。 - `string`: 用于搜索文档中字符串内容。它可以是一个字符串、正则表达式或者字符串列表。 示例代码: ```python soup = BeautifulSoup(html, "html.parser") all_a_tags = soup.find_all("a") class_py1 = soup.find_all("a", {"class": "py1"}) print(all_a_tags) print(class_py1) ``` 这段代码会打印出 HTML 文档中所有的 `<a>` 标签,以及所有类属性为 `"py1"` 的 `<a>` 标签。 除了 `find_all` 方法,BeautifulSoup 还提供了其他查找函数,包括: - `.find()`: 用于查找单个结果,返回第一个匹配的标签。 - `.find_parents()` 和 `.find_parent()`: 用于向上搜索文档树,查找符合条件的父节点或所有父节点。 - `.find_next_siblings()` 和 `.find_next_sibling()`: 用于搜索当前节点之后的兄弟节点。 - `.find_previous_siblings()` 和 `.find_previous_sibling()`: 用于搜索当前节点之前的兄弟节点。 - `.find_all_next()` 和 `.find_next()`: 用于搜索当前节点之后的所有节点和下一个节点。 - `.find_all_previous()` 和 `.find_previous()`: 用于搜索当前节点之前的所有节点和上一个节点。 每个函数都有各自的搜索范围和用途,可以根据实际需求选择合适的方法。 ### CSS 选择器 BeautifulSoup 还支持 CSS 选择器,通过 `.select()` 方法可以使用 CSS 选择器来查找节点: ```python soup = BeautifulSoup(html, "html.parser") tags = soup.select("div.myClass > a") ``` 在这个例子中,`.select()` 方法搜索所有在 `div` 元素的 `myClass` 类里的直接子节点 `a` 标签。CSS 选择器是一个非常强大的功能,可以让你以与 CSS 相同的方式选择 HTML 元素。 ### 正则表达式 当你需要对查找条件进行复杂的匹配时,可以使用正则表达式: ```python import re soup = BeautifulSoup(html, "html.parser") tags = soup.find_all(re.compile("^b")) ``` 这段代码查找所有以字母 'b' 开头的标签,例如 `<body>`、`<b>` 等。 ### Lambda 表达式 对于更加复杂的搜索,可以使用 lambda 表达式作为参数: ```python soup = BeautifulSoup(html, "html.parser") tags = soup.find_all(lambda tag: tag.get_text() == "Python") ``` 这里,`find_all` 方法使用了一个 lambda 函数来筛选出所有标签文本内容为 "Python" 的标签。 ## 6. 结果的输出与导航 一旦你找到了需要的标签,你可能会想要获取标签的内容或者进一步导航到其他相关的标签。BeautifulSoup 提供了简单的方法来实现这些功能。 ### 获取内容 - `.get_text()`: 提取标签内的文本内容。 - `.attrs`: 获取标签的所有属性。 - `.get('attribute')`: 获取标签的特定属性值。 ### 导航 - `.parent`: 访问标签的父节点。 - `.children`: 访问标签的直接子节点。 - `.descendants`: 访问标签的所有子孙节点。 - `.next_sibling` 和 `.previous_sibling`: 访问标签的下一个和上一个兄弟节点。 ### 输出 最后,你可能需要将处理的结果输出到文件或控制台: ```python with open("output.html", "w", encoding="utf-8") as file: file.write(soup.prettify()) ``` 这段代码将格式化后的 HTML 内容写入到名为 "output.html" 的文件中。 通过以上方法,你可以有效地利用 BeautifulSoup 库进行 HTML 和 XML 的解析和数据提取。 > 虽然 BeautifulSoup 非常强大,但它并不适用于所有的网页解析场景,特别是那些依赖于 JavaScript 动态生成内容的网页。在处理这类网页时,你可能需要使用像 Selenium 这样的工具来处理 JavaScript 渲染的内容。 Last modification:March 1, 2024 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 如果觉得我的文章对你有用,请随意赞赏