HTML文档解析之Beautiful Soup

一. 引入

Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.

二. 安装

pip install beautifulsoup4

三. 快速开始

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>

<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">It's a good story</p>
<p>
<!--Hey, buddy. Want to buy a used parser?-->
</p>
"""
  • 如何使用?

    将一段文档传入BeautifulSoup 的构造方法,就能得到一个文档的对象, 可以传入一段字符串一个文件句柄.

from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html>data</htmol>")
  • 使用BeautifulSoup解析这段代码,能够得到一个 BeautifulSoup 的对象,使用该对象下的prettify()方法,能按照标准的缩进格式的结构输出:

四. 常用方法

1. 获取标签

  • BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,它支持 遍历文档树 和 搜索文档树 中描述的大部分的方法。因为 BeautifulSoup 对象并不是真正的HTML或XML的tag,所以它没有name和attribute属性.但有时查看它的 .name 属性是很方便的,所以 BeautifulSoup 对象包含了一个值为 “[document]” 的特殊属性 .name

  • 可以通过 soup.p 来获得文档中第一个 p 标签,当然了,你想要获得什么标签, 通过**.name**就能获得任意标签。

    通过上图可以看出,soup.p的类型是 bs4.element.Tag对象,Tag对象也能通过 .name方法,获得标签,如下:

    • 通过 .name方法获得到文档中第一个p标签下的b标签
  • 获取多个标签,如上,我们发现,只能获得到文档中的一个p标签,可以通过**find_all()**方法获得多个p标签。如下图:

  • find_all返回的是一个列表,列表中每一个元素为 Tag对象

  • 如需获得一个标签,也可以使用find方法,使用与find_all类似,只是返回值是一个 Tag对象。这里,提一点,soup.find_all(‘p’)可以简写成soup(‘p’),这两个是等价的。

  • 添加过滤条件,获取到想要的标签:

    • 假设,我要获取 p 标签中 class属性名称为"story"的p 标签

      PS: 这里需要注意一下,class是python中的关键字,当需要使用class属性时,需要使用**class_**加以区分。当然了,你也可以通过该标签的其它属性,如 id=xxx,这样也行。当然,还有其它写法,如下:
  • 过滤条件也可以是正则表达式

    • 假设,我要获取文档中 a标签,href属性包含 lacie,如下:

PS:以上,不论是 find_all还是find都适用,注意一点,过滤条件可以写自行组合,如下:

 soup.find('a',class_='story',href=re.compile(r'xxxx'))
  • 使用CSS选择器来查找标签
  1. 通过标签名来查找,如下:

    从上图可以看出,跟 find_all() 差不多。

  2. 通过CSS的类名查找,如下:

  3. 通过tag的id查找,如下:

  4. 同时用多种CSS选择器查询元素,如下:(可以使用逗号将两个CSS选择器分隔开来)

    PS:soup.select()适合熟悉CSS语法的人使用(当然不是绝对的,不了解CSS也能够使用),这里注意一点,不管是获得的结果是几个,返回的都是一个列表,列表中的每一个元素都是一个 Tag对象,可以再次对 Tag对象使用select find find_all等方法;附一张,如何在浏览器中,获得某个标签的CSS选择器:

2. 获取标签文本内容

  • 使用 text方法,(注意返回的标签下所有的文本内容,返回的类型是str

  • 使用 get_text() 方法,与 text方法一样,没有区别。

  • .string 方法,

  • 很奇怪,竟然返回了None,这是为什么呢?

如果tag只有一个 NavigableString 类型子节点,那么这个tag可以使用 .string 得到子节点。如果tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None 。什么意思呢?请看下图:

PS:.string方法获得的并不是str类型,而是 <class ‘bs4.element.NavigableString’>,text 和 get_text()方法是获得某个标签下所有的文本内容,而string方法只能获得 tag标签下只有一个 NavigableString 类型子节点的文本内容。

3. 获取标签属性

  • 使用 tag[‘xxx’],假设,我需要获取到 a标签中的href属性,如下图:

    PS:注意一下,当标签没有该属性时,会报错。

  • 使用 tag.get(‘href’,‘http://www.csdn.com’),如果该标签没有href属性,将会把http://www.csdn.com赋值给变量。默认是None,与上一种方法区别在于,属性不存在的话,不会报错。

  • 使用 tag.attrs 属性字典进行取值,如下图所示:

五. 关于文档解析器

  • Beautiful Soup为不同的解析器提供了相同的接口,但解析器本身时有区别的.同一篇文档被不同的解析器解析后可能会生成不同结构的树型文档。
  • 以下列出两种常用文档解析器:
解析器 使用方法 优势 劣势
Python标准库 BeautifulSoup(html文档, “html.parser”) 1.Python的内置标准库 2.执行速度适中3. 文档容错能力强 Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
lxml HTML 解析器 BeautifulSoup(html文档, “lxml”) 1. 速度快 2. 文档容错能力强 需要安装 lxml模块,pip install lxml

End…

Guess you like

Origin blog.csdn.net/weixin_42218582/article/details/97431849