- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
11.5 用 BeautifulSoup 模块解析 HTML
Beautiful Soup是一个模块,用于从HTML页面中提取信息(用于这个目的时,它比正则表达式好很多)。BeautifulSoup模块的名称是bs4(表示Beautiful Soup,第4版)。要安装它,需要在命令行中运行pip install beautifulsoup4(关于安装第三方模块的指导,请查看附录 A)。虽然安装时使用的名字是beautifulsoup4,但要导入它,就使用import bs4。
在本章中,Beautiful Soup的例子将解析(即分析并确定其中的一些部分)硬盘上的一个HTML文件。在IDLE中打开一个新的文件编辑器窗口,输入以下代码,并保存为example.html。或者,从http://nostarch.com/automatestuff/下载它。
<!-- 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">Al Sweigart</span></p> </body></html>
你可以看到,既使一个简单的HTML文件,也包含许多不同的标签和属性。对于复杂的网站,事情很快就变得令人困惑。好在,Beautiful Soup让处理HTML变得容易很多。
11.5.1 从HTML创建一个BeautifulSoup对象
bs4.BeautifulSoup()函数调用时需要一个字符串,其中包含将要解析的HTML。bs4.BeautifulSoup()函数返回一个BeautifulSoup对象。在交互式环境中输入以下代码,同时保持计算机与因特网的连接:
>>> import requests, bs4 >>> res = requests.get('http://nostarch.com') >>> res.raise_for_status() >>> noStarchSoup = bs4.BeautifulSoup(res.text) >>> type(noStarchSoup) < class 'bs4.BeautifulSoup'>
这段代码利用requests.get()函数从No Starch Press网站下载主页,然后将响应结果的text属性传递给bs4.BeautifulSoup()。它返回的BeautifulSoup对象保存在变量noStarchSoup中。
也可以向bs4.BeautifulSoup()传递一个File对象,从硬盘加载一个HTML文件。在交互式环境中输入以下代码(确保example.html文件在工作目录中):
>>> exampleFile = open('example.html') >>> exampleSoup = bs4.BeautifulSoup(exampleFile) >>> type(exampleSoup) < class 'bs4.BeautifulSoup'>
有了BeautifulSoup对象之后,就可以利用它的方法,定位HTML文档中的特定部分。
11.5.2 用select()方法寻找元素
针对你要寻找的元素,调用method()方法,传入一个字符串作为CSS“选择器”,这样就可以取得Web页面元素。选择器就像正则表达式:它们指定了要寻找的模式,在这个例子中,是在HTML页面中寻找,而不是普通的文本字符串。
完整地讨论 CSS 选择器的语法超出了本书的范围(在 http://nostarch.com/automatestuff/的资源中,有很好的选择器指南),但这里有一份选择器的简单介绍。表11-2举例展示了大多数常用CSS选择器的模式。
表11-2 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元素的方式。针对BeautifulSoup对象中的HTML的每次匹配,列表中都有一个Tag对象。Tag值可以传递给str()函数,显示它们代表的HTML标签。Tag值也可以有attrs属性,它将该Tag的所有HTML属性作为一个字典。利用前面的example.html文件,在交互式环境中输入以下代码:
>>> import bs4 >>> exampleFile = open('example.html') >>> exampleSoup = bs4.BeautifulSoup(exampleFile.read()) >>> elems = exampleSoup.select('#author') >>> type(elems) < class 'list'> >>> len(elems) 1 >>> type(elems[0]) < class 'bs4.element.Tag'> >>> elems[0].getText() 'Al Sweigart' >>> str(elems[0]) '< span id="author">Al Sweigart< /span>' >>> 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:// inventwithpython.com">my website< /a>.< /p>' >>> pElems[0].getText() 'Download my Python book from my website.' >>> str(pElems[1]) '< p class="slogan">Learn Python the easy way!< /p>' >>> pElems[1].getText() 'Learn Python the easy way!' >>> str(pElems[2]) '< p>By < span id="author">Al Sweigart< /span>< /p>' >>> pElems[2].getText() 'By Al Sweigart'
这一次,select()给我们一个列表,包含3次匹配,我们将它保存在pElems中。在pElems[0]、pElems[1]和pElems[2]上使用str(),将每个元素显示为一个字符串,并在每个元素上使用getText(),显示它的文本。
11.5.3 通过元素的属性获取数据
Tag对象的get()方法让我们很容易从元素中获取属性值。向该方法传入一个属性名称的字符串,它将返回该属性的值。利用example.html,在交互式环境中输入以下代码:
>>> import bs4 >>> soup = bs4.BeautifulSoup(open('example.html')) >>> spanElem = soup.select('span')[0] >>> str(spanElem) '< span id="author">Al Sweigart< /span>' >>> spanElem.get('id') 'author' >>> spanElem.get('some_nonexistent_addr') == None True >>> spanElem.attrs {'id': 'author'}
这里,我们使用select()来寻找所有< span>元素,然后将第一个匹配的元素保存在spanElem中。将属性名'id'传递给get(),返回该属性的值'author'。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论