企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# BeautifulSoup 教程 > 原文: [http://zetcode.com/python/beautifulsoup/](http://zetcode.com/python/beautifulsoup/) BeautifulSoup 教程是 BeautifulSoup Python 库的入门教程。 这些示例查找标签,遍历文档树,修改文档和刮取网页。 ## BeautifulSoup BeautifulSoup 是用于解析 HTML 和 XML 文档的 Python 库。 它通常用于网页抓取。 BeautifulSoup 将复杂的 HTML 文档转换为复杂的 Python 对象树,例如标记,可导航字符串或注释。 ## 安装 BeautifulSoup 我们使用`pip3`命令安装必要的模块。 ```py $ sudo pip3 install lxml ``` 我们需要安装 BeautifulSoup 使用的`lxml`模块。 ```py $ sudo pip3 install bs4 ``` 上面的命令将安装 BeautifulSoup。 ## HTML 文件 在示例中,我们将使用以下 HTML 文件: `index.html` ```py <!DOCTYPE html> <html> <head> <title>Header</title> <meta charset="utf-8"> </head> <body> <h2>Operating systems</h2> <ul id="mylist" style="width:150px"> <li>Solaris</li> <li>FreeBSD</li> <li>Debian</li> <li>NetBSD</li> <li>Windows</li> </ul> <p> FreeBSD is an advanced computer operating system used to power modern servers, desktops, and embedded platforms. </p> <p> Debian is a Unix-like computer operating system that is composed entirely of free software. </p> </body> </html> ``` ## BeautifulSoup 简单示例 在第一个示例中,我们使用 BeautifulSoup 模块获取三个标签。 `simple.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print(soup.h2) print(soup.head) print(soup.li) ``` 该代码示例将打印三个标签的 HTML 代码。 ```py from bs4 import BeautifulSoup ``` 我们从`bs4`模块导入`BeautifulSoup`类。 `BeautifulSoup`是从事工作的主要类。 ```py with open("index.html", "r") as f: contents = f.read() ``` 我们打开`index.html`文件并使用`read()`方法读取其内容。 ```py soup = BeautifulSoup(contents, 'lxml') ``` 创建了`BeautifulSoup`对象; HTML 数据将传递给构造器。 第二个选项指定解析器。 ```py print(soup.h2) print(soup.head) ``` 在这里,我们打印两个标签的 HTML 代码:`h2`和`head`。 ```py print(soup.li) ``` 有多个`li`元素; 该行打印第一个。 ```py $ ./simple.py <h2>Operating systems</h2> <head> <title>Header</title> <meta charset="utf-8"/> </head> <li>Solaris</li> ``` 这是输出。 ## BeautifulSoup 标签,名称,文本 标记的`name`属性给出其名称,`text`属性给出其文本内容。 `tags_names.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print("HTML: {0}, name: {1}, text: {2}".format(soup.h2, soup.h2.name, soup.h2.text)) ``` 该代码示例打印`h2`标签的 HTML 代码,名称和文本。 ```py $ ./tags_names.py HTML: <h2>Operating systems</h2>, name: h2, text: Operating systems ``` 这是输出。 ## BeautifulSoup 遍历标签 使用`recursiveChildGenerator()`方法,我们遍历 HTML 文档。 `traverse_tree.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') for child in soup.recursiveChildGenerator(): if child.name: print(child.name) ``` 该示例遍历文档树并打印所有 HTML 标记的名称。 ```py $ ./traverse_tree.py html head title meta body h2 ul li li li li li p p ``` 在 HTML 文档中,我们有这些标签。 ## BeautifulSoup 子元素 使用`children`属性,我们可以获取标签的子级。 `get_children.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') root = soup.html root_childs = [e.name for e in root.children if e.name is not None] print(root_childs) ``` 该示例检索`html`标记的子代,将它们放置在 Python 列表中,然后将其打印到控制台。 由于`children`属性还返回标签之间的空格,因此我们添加了一个条件,使其仅包含标签名称。 ```py $ ./get_children.py ['head', 'body'] ``` `html`标签有两个子元素:`head`和`body`。 ## BeautifulSoup 后继元素 使用`descendants`属性,我们可以获得标签的所有后代(所有级别的子级)。 `get_descendants.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') root = soup.body root_childs = [e.name for e in root.descendants if e.name is not None] print(root_childs) ``` 该示例检索`body`标记的所有后代。 ```py $ ./get_descendants.py ['h2', 'ul', 'li', 'li', 'li', 'li', 'li', 'p', 'p'] ``` 这些都是`body`标签的后代。 ## BeautifulSoup 网页抓取 请求是一个简单的 Python HTTP 库。 它提供了通过 HTTP 访问 Web 资源的方法。 `scraping.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup import requests as req resp = req.get("http://www.something.com") soup = BeautifulSoup(resp.text, 'lxml') print(soup.title) print(soup.title.text) print(soup.title.parent) ``` 该示例检索一个简单网页的标题。 它还打印其父级。 ```py resp = req.get("http://www.something.com") soup = BeautifulSoup(resp.text, 'lxml') ``` 我们获取页面的 HTML 数据。 ```py print(soup.title) print(soup.title.text) print(soup.title.parent) ``` 我们检索标题的 HTML 代码,其文本以及其父级的 HTML 代码。 ```py $ ./scraping.py <title>Something.</title> Something. <head><title>Something.</title></head> ``` 这是输出。 ## BeautifulSoup 美化代码 使用`prettify()`方法,我们可以使 HTML 代码看起来更好。 `prettify.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup import requests as req resp = req.get("http://www.something.com") soup = BeautifulSoup(resp.text, 'lxml') print(soup.prettify()) ``` 我们美化了一个简单网页的 HTML 代码。 ```py $ ./prettify.py <html> <head> <title> Something. </title> </head> <body> Something. </body> </html> ``` 这是输出。 ## BeautifulSoup 通过 ID 查找元素 使用`find()`方法,我们可以通过各种方式(包括元素 ID)查找元素。 `find_by_id.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') #print(soup.find("ul", attrs={ "id" : "mylist"})) print(soup.find("ul", id="mylist")) ``` 该代码示例查找具有`mylist` ID 的`ul`标签。 带注释的行是执行相同任务的另一种方法。 ## BeautifulSoup 查找所有标签 使用`find_all()`方法,我们可以找到满足某些条件的所有元素。 `find_all.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') for tag in soup.find_all("li"): print("{0}: {1}".format(tag.name, tag.text)) ``` 该代码示例查找并打印所有`li`标签。 ```py $ ./find_all.py li: Solaris li: FreeBSD li: Debian li: NetBSD ``` 这是输出。 `find_all()`方法可以获取要搜索的元素列表。 `find_all2.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') tags = soup.find_all(['h2', 'p']) for tag in tags: print(" ".join(tag.text.split())) ``` 该示例查找所有`h2`和`p`元素并打印其文本。 `find_all()`方法还可以使用一个函数,该函数确定应返回哪些元素。 `find_by_fun.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup def myfun(tag): return tag.is_empty_element with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') tags = soup.find_all(myfun) print(tags) ``` 该示例打印空元素。 ```py $ ./find_by_fun.py [<meta charset="utf-8"/>] ``` 文档中唯一的空元素是`meta`。 也可以使用正则表达式查找元素。 `regex.py` ```py #!/usr/bin/python3 import re from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') strings = soup.find_all(string=re.compile('BSD')) for txt in strings: print(" ".join(txt.split())) ``` 该示例打印包含`"BSD"`字符串的元素的内容。 ```py $ ./regex.py FreeBSD NetBSD FreeBSD is an advanced computer operating system used to power modern servers, desktops, and embedded platforms. ``` 这是输出。 ## BeautifulSoup CSS 选择器 通过`select()`和`select_one()`方法,我们可以使用一些 CSS 选择器来查找元素。 `select_nth_tag.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print(soup.select("li:nth-of-type(3)")) ``` 本示例使用 CSS 选择器来打印第三个`li`元素的 HTML 代码。 ```py $ ./select_nth_tag.py <li>Debian</li> ``` 这是第三个`li`元素。 CSS 中使用`#`字符通过 ID 属性选择标签。 `select_by_id.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print(soup.select_one("#mylist")) ``` 该示例打印具有`mylist` ID 的元素。 ## BeautifulSoup 附加元素 `append()`方法将新标签附加到 HTML 文档。 `append_tag.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') newtag = soup.new_tag('li') newtag.string='OpenBSD' ultag = soup.ul ultag.append(newtag) print(ultag.prettify()) ``` 该示例附加了一个新的`li`标签。 ```py newtag = soup.new_tag('li') newtag.string='OpenBSD' ``` 首先,我们使用`new_tag()`方法创建一个新标签。 ```py ultag = soup.ul ``` 我们获得对`ul`标签的引用。 ```py ultag.append(newtag) ``` 我们将新创建的标签附加到`ul`标签。 ```py print(ultag.prettify()) ``` 我们以整齐的格式打印`ul`标签。 ## BeautifulSoup 插入元素 `insert()`方法在指定位置插入标签。 `insert_tag.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') newtag = soup.new_tag('li') newtag.string='OpenBSD' ultag = soup.ul ultag.insert(2, newtag) print(ultag.prettify()) ``` 该示例将第三个位置的`li`标签插入`ul`标签。 ## BeautifulSoup 替换文字 `replace_with()`替换元素的文本。 `replace_text.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') tag = soup.find(text="Windows") tag.replace_with("OpenBSD") print(soup.ul.prettify()) ``` 该示例使用`find()`方法查找特定元素,并使用`replace_with()`方法替换其内容。 ## BeautifulSoup 删除元素 `decompose()`方法从树中删除标签并销毁它。 `decompose_tag.py` ```py #!/usr/bin/python3 from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') ptag2 = soup.select_one("p:nth-of-type(2)") ptag2.decompose() print(soup.body.prettify()) ``` 该示例删除了第二个`p`元素。 在本教程中,我们使用了 Python BeautifulSoup 库。 您可能也会对以下相关教程感兴趣: [Pyquery 教程](/python/pyquery), [Python 教程](/lang/python/), [Python 列表推导](/articles/pythonlistcomprehensions/), [OpenPyXL 教程](/articles/openpyxl/),Python Requests 教程和 [Python CSV 教程](/python/csv/)。