BeautifUl Soup
是一个模块,用于从 HTML
页面中提取信息(用于这个目的时,它比正则表达式好很多)。
BeautifUlSoup
模块的名称是 bs4
(表示 Beautiful Soup
,第4版)。
要安装它,需要在命令行中运行 pip install beautifulsoup4
(关于安装第三方模块的指导,请查看附录A)。
虽然安装时使用的名字是 beautifulsup4
,但要导入它,就使用 import bs4
。
在本章中,Beautiful Soup
的例子将解析(即分析并确定其中的一些部分)硬盘上的一个 HTML 文件。
在 IDLE 中打开一个新的文件编辑器窗口,
输入以下代码,并保存为 example.html
。
或者,从 http://nostarch.com/automatestuff/ 下载它。
html_cnt = '''<!-- This is the example.html example file.-->
<html><head><title>The Website Title</title></head>
<body>
<p>Download my <strong>Python</strong> book from <a href="http://
inventwithpython.com">my website</a>.</p>
<p class="slogan">Learn Python the easy way!</p>
<p>By <span id="author">A1 Sweigart</span></p>
</body></html>
'''
import requests, bs4
res = requests.get('https://www.baidu.com/')
res.raise_for_status()
noStarchSoup = bs4.BeautifulSoup(res.text, 'lxml')
type(noStarchSoup)
bs4.BeautifulSoup
这段代码利用 requests.get()
函数从 No Starch Press
网站下载主页,
然后将响应结果的 text
属性传递给 bs4.BeautifulSoup()
。
它返回的 BeautifiUSoup
对象保存在变量 noStarchSoup
中。
也可以向 bs4.BeautifUlSoup()
传递一个 File
对象,
从硬盘加载一个 HTML 文件。
在交互式环境中输入以下代码(确保 example.html
文件在工作目录中):
# exampleFile = open ('RomeoAndJuliet.txt')
exampleFile = open ('/data/demo/example.html')
exampleSoup = bs4.BeautifulSoup(exampleFile, 'html.parser')
type(exampleSoup)
bs4.BeautifulSoup
有了 BeautiflilSoup
对象之后,就可以利用它的方法,
定位HTML文档中的特定部分。
用 select()
方法寻找元素
针对要寻找的元素,调用method方法,传入一个字符串作为CSS“选择器”,
这样就可以取得 Web 页面元素。
选择器就像正则表达式:它们指定了要寻找的模式,
在这个例子中,是在HTML页面中寻找,而不是普通的文本字符串。
完整地讨论 CSS
选择器的语法超出了本书的范围
(在 http://nostarch.com/automatestuff/
的资源中,有很好的选择器指南),
但这里有一份选择器的简单介绍。
下面展示了大多数常用 CSS
选择器的模式。
传递给select()方法的选择器 | 将匹配 |
---|---|
soup.select('div') |
所有名为<div> 的元素 |
soup.select('#author') |
带有id属性为author的元素 |
soup.select('.notice') |
所有使用CSS class属性名为notice的元素 |
soup.select('div span') |
所有在<div> 元素之内的<span> 元素 |
soup.select('div>span') |
所有直接在<div> 元素之内的<span> 元素,中间没有其他元素 |
soup.select('input[name]') |
所有名为<input> ,并有一个name属性,其值无所谓的元素 |
soup.select('input[type="button"]') |
所有名为<input> ,并有一个type属性,其值为button的元素 |
不同的选择器模式可以组合起来,形成复杂的匹配。
例如, soup.select('p #author')
将匹配所有 id
属性为 author
的元素,
只要它也在一个 <p>
元素之内。
select()
方法将返回一个 Tag
对象的列表,这是 Beautiful Soup
表示一个 HTML
元素的方式。
针对 BeautifiilSoup
对象中的 HTML
的每次匹配, 列表中都有一个 Tag
对象。
Tag
值可以传递给 str()
函数,显示它们代表的 HTML
标签。
Tag
值也可以有 attrs
属性,它将该 Tag
的所有 HTML
属性作为一个字典。
利用前面的 example.html
文件,在交互式环境中输入以下代码:
import bs4
exampleFile = open('/data/demo/example.html')
exampleSoup = bs4.BeautifulSoup(exampleFile.read(), 'lxml')
elems = exampleSoup.select('#author')
type(elems)
bs4.element.ResultSet
len(elems)
type(elems[0])
elems[0].getText()
str(elems[0])
elems[0].attrs
{'id': 'author'}
这段代码将带有 id="author"
的元素,从示例 HTML
中找出来。
使用 select('#author')
返回一个列表,其中包含所有带有 id="author"
的元素。
将这个Tag
对象的列表保存在变量中 elems
, len(elems)
告诉列表中只有一个 Tag
对象,只有一次匹配。
在该元素上调用 getText()
方法,返回该元素的文本,或内部的 HTML。
一个元素的文本是在开始和结束标签之间的内容:在这个例子中,就是 'Al Sweigart'
。
将该元素传递给 str()
,这将返回一个字符串,其中包含开始和结束标签,以及该元素的文本。
最后, attrs
给了一个字典,包含该元素的属性 'id'
,以及 id
属性的值 'author'
。
也可以从 BeautifulSoup
对象中找出 <p>
元素。
在交互式环境中输入以下代码:
pElems = exampleSoup.select('p')
str(pElems[0])
'<p>Download my <strong>Python</strong> book from <a href="http://\ninventwithpython.com">my website</a>.</p>'
pElems[0].getText()
str(pElems[1])
pElems[1].getText()
str(pElems[2])
pElems[2].getText()
'By A1 Sweigart'
import bs4
soup = bs4.BeautifulSoup(open('/data/demo/example.html'), 'lxml')
spanElem = soup.select('span')[0]
str(spanElem)
'<span id="author">A1 Sweigart</span>'
spanElem.get('id')
spanElem.get('some_nonexistent_addr') == None
spanElem.attrs
{'id': 'author'}
这里使用 select()
来寻找所有 <span>
元素,将第一个匹配的元素保存在 spanElem
中。
将属性名 'id'
传递给 get()
,返回该属性的值 'author'
。