PythonBeautifulSoup教程是BeautifulSoupPython库的入门教程。示例包括查找标签、遍历文档树、修改文档和抓取网页。
美丽汤
BeautifulSoup是一个用于解析HTML和XML文档的Python库。它通常用于网页抓取。BeautifulSoup将复杂的HTML文档转换为复杂的Python对象树,例如标签、可导航字符串或注释。
安装BeautifulSoup
我们使用pip3
命令来安装必要的模块。
$ sudo pip3 install lxml
我们需要安装BeautifulSoup使用的lxml
模块。
$ sudo pip3 install bs4
BeautifulSoup使用上述命令安装。
HTML文件
在示例中,我们将使用以下HTML文件:
<!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>
简单的PythonBeautifulSoup示例
在第一个示例中,我们使用BeautifulSoup模块获取三个标签。
#!/usr/bin/python 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代码。
from bs4 import BeautifulSoup
我们从bs4
模块导入BeautifulSoup
类。BeautifulSoup
是执行工作的主要类。
with open('index.html', 'r') as f: contents = f.read()
我们打开index.html
文件并使用read
方法读取它的内容。
soup = BeautifulSoup(contents, 'lxml')
BeautifulSoup
对象被创建;HTML数据被传递给构造函数。第二个选项指定解析器。
print(soup.h2) print(soup.head)
这里我们打印了两个标签的HTML代码:h2
和head
。
print(soup.li)
有多个li
元素;该行打印第一个。
$ ./simple.py <h2>Operating systems</h2> <head> <title>Header</title> <meta charset="utf-8"/> </head> <li>Solaris</li>
BeautifulSoup标签、名称、文本
标签的name
属性给出了它的名字,text
属性给出了它的文本内容。
#!/usr/bin/python from bs4 import BeautifulSoup with open('index.html', 'r') as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print(f'HTML: {soup.h2}, name: {soup.h2.name}, text: {soup.h2.text}')
代码示例打印h2
标签的HTML代码、名称和文本。
$ ./tags_names.py HTML: <h2>Operating systems</h2>, name: h2, text: Operating systems
BeautifulSoup遍历标签
使用recursiveChildGenerator
方法我们遍历HTML文档。
#!/usr/bin/python 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标记的名称。
$ ./traverse_tree.py html head title meta body h2 ul li li li li li p p
在HTML文档中我们有这些标签。
BeautifulSoup子元素
通过children
属性,我们可以获得标签的子元素。
#!/usr/bin/python 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
属性还会返回标签之间的空格,因此我们添加了一个条件以仅包含标签名称。
$ ./get_children.py ['head', 'body']
html
标签有两个子标签:head
和body
。
BeautifulSoup元素后代
通过descendants
属性,我们可以获得标签的所有后代(所有级别的子代)。
#!/usr/bin/python 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
标记的所有后代。
$ ./get_descendants.py ['h2', 'ul', 'li', 'li', 'li', 'li', 'li', 'p', 'p']
这些都是body
标签的后代。
BeautifulSoup网页抓取
Requests是一个简单的PythonHTTP库。它提供了通过HTTP访问Web资源的方法。
#!/usr/bin/python from bs4 import BeautifulSoup import requests as req resp = req.get('http://webcode.me') soup = BeautifulSoup(resp.text, 'lxml') print(soup.title) print(soup.title.text) print(soup.title.parent)
该示例检索一个简单网页的标题。它还打印其父项。
resp = req.get('http://webcode.me') soup = BeautifulSoup(resp.text, 'lxml')
我们获取页面的HTML数据。
print(soup.title) print(soup.title.text) print(soup.title.parent)
我们检索标题的HTML代码、其文本及其父项的HTML代码。
$ ./scraping.py <title>My html page</title> My html page <head> <meta charset="utf-8"/> <meta content="width=device-width, initial-scale=1.0" name="viewport"/> <title>My html page</title> </head>
BeautifulSoup美化代码
通过prettify
方法,我们可以使HTML代码看起来更好。
#!/usr/bin/python from bs4 import BeautifulSoup import requests as req resp = req.get('http://webcode.me') soup = BeautifulSoup(resp.text, 'lxml') print(soup.prettify())
我们美化了一个简单网页的HTML代码。
$ ./prettify.py <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> <meta content="width=device-width, initial-scale=1.0" name="viewport"/> <title> My html page </title> </head> <body> <p> Today is a beautiful day. We go swimming and fishing. </p> <p> Hello there. How are you? </p> </body> </html>
内置网络服务器的BeautifulSoup抓取
我们还可以使用简单的内置HTTP服务器提供HTML页面。
$ mkdir public $ cp index.html public/
我们创建一个public
目录,并将index.html
复制到那里。
$ python -m http.server --directory public Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
然后我们启动PythonHTTP服务器。
#!/usr/bin/python from bs4 import BeautifulSoup import requests as req resp = req.get('http://localhost:8000/') soup = BeautifulSoup(resp.text, 'lxml') print(soup.title) print(soup.body)
现在我们从本地运行的服务器获取文档。
BeautifulSoup通过Id查找元素
使用find
方法,我们可以通过各种方式查找元素,包括元素id。
#!/usr/bin/python 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
方法,我们可以找到满足某些条件的所有元素。
#!/usr/bin/python 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(f'{tag.name}: {tag.text}')
代码示例查找并打印所有li
标签。
$ ./find_all.py li: Solaris li: FreeBSD li: Debian li: NetBSD li: Windows
find_all
方法可以获取要搜索的元素列表。
#!/usr/bin/python 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
方法也可以采用一个函数来确定应返回哪些元素。
#!/usr/bin/python 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)
该示例打印空元素。
$ ./find_by_fun.py [<meta charset="utf-8"/>]
文档中唯一的空元素是meta
。
也可以使用正则表达式查找元素。
#!/usr/bin/python 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”字符串的元素的内容。
$ ./regex.py FreeBSD NetBSD FreeBSD is an advanced computer operating system used to power modern servers, desktops, and embedded platforms.
BeautifulSoupCSS选择器
通过select
和select_one
方法,我们可以使用一些CSS选择器来查找元素。
#!/usr/bin/python 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代码。
$ ./select_nth_tag.py <li>Debian</li>
这是第三个li
元素。
#字符在CSS中用于根据标签的id属性选择标签。
#!/usr/bin/python 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文档。
#!/usr/bin/python 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
标记。
newtag = soup.new_tag('li') newtag.string='OpenBSD'
首先,我们使用new_tag
方法创建一个新标签。
ultag = soup.ul
我们得到了对ul
标签的引用。
ultag.append(newtag)
我们将新创建的标签附加到ul
标签。
print(ultag.prettify())
我们以整洁的格式打印ul
标签。
BeautifulSoup插入元素
insert
方法在指定位置插入一个标签。
#!/usr/bin/python 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())
该示例在ul
标记的第三个位置插入一个li
标记。
BeautifulSoup替换文本
replace_with
替换元素的文本。
#!/usr/bin/python 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
方法从树中删除一个标签并将其销毁。
#!/usr/bin/python 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
元素。
在本教程中,我们使用了PythonBeautifulSoup库。
阅读Python教程或列出所有Python教程。