爬虫利器 Beautiful Soup 之遍历文档

Beautiful Soup 简介Beautiful Soup 是一个可以从 html 或 XML 文件中提取数据的 Python 库,它提供了一些简单的操作方式来帮助你处理文档导航,查找,修改文档等繁琐的工作 。因为使用简单,所以 Beautiful Soup 会帮你节省不少的工作时间 。
Beautiful Soup 安装你可以使用如下命令安装 Beautiful Soup 。二选一即可 。
$ easy_install beautifulsoup4$ pip install beautifulsoup4Beautiful Soup 不仅支持 Python 标准库中的 HTML 解析器,还支持很多第三方的解析器,比如 lxml,html5lib 等 。初始化 Beautiful Soup 对象时如果不指定解析器,那么 Beautiful Soup 将会选择最合适的解析器(前提是你的机器安装了该解析器)来解析文档,当然你也可以手动指定解析器 。这里推荐大家使用 lxml 解析器,功能强大,方便快捷,而且该解析器是唯一支持 XML 的解析器 。
你可以使用如下命令来安装 lxml 解析器 。二选一即可 。
$ easy_install lxml$ pip install lxmlBeautiful Soup 小试牛刀Beautiful Soup 使用来起来非常简单,你只需要传入一个文件操作符或者一段文本即可得到一个构建完成的文档对象,有了该对象之后,就可以对该文档做一些我们想做的操作了 。而传入的文本大都是通过爬虫爬取过来的,所以 Beautiful Soup 和 requests 库结合使用体验更佳 。
# demo 1from bs4 import BeautifulSoup# soup = BeautifulSoup(open("index.html"))soup = BeautifulSoup("<html><head><title>index</title></head><body>content</body></html>", "lxml") # 指定解析器print(soup.head)# 输出结果<head><title>index</title></head>Beautiful Soup 将复杂的 HTML 文档转换成一个复杂的树形结构,每个节点都是 Python 对象,所有对象可以归纳为 4 种: Tag,NavigableString,BeautifulSoup,Comment 。
Tag 就是 HTML 的一个标签,比如 div,p 标签等,也是我们用的最多的一个对象 。
NavigableString 指标签内部的文字,直译就是可遍历的字符串 。
BeautifulSoup 指一个文档的全部内容,可以当成一个 Tag 来处理 。
Comment 是一个特殊的 NavigableString,其输出内容不包括注视内容 。
为了故事的顺利发展,我们先定义一串 HTML 文本,下文的所有例子都是基于这段文本的 。
html_doc = """<html><head><title>index</title></head><body><p class="title"><b>首页</b></p><p class="main">我常用的网站<a href=https://www.isolves.com/it/cxkf/yy/Python/2022-07-04/"https://www.google.com" class="website" id="google">GoogleBaiduBing

...

...

"""子节点Tag 有两个很重要的属性,name 和 attributes 。期中 name 就是标签的名字,attributes 是标签属性 。标签的名字和属性是可以被修改的,注意,这种修改会直接改变 BeautifulSoup 对象 。
# demo 2soup = BeautifulSoup(html_doc, "lxml");p_tag = soup.pprint(p_tag.name)print(p_tag["class"])print(p_tag.attrs)p_tag.name="myTag" # attrs 同样可被修改,操作同字典print(p_tag)#输出结果p['title']{'class': ['title']}<myTag class="title"><b>首页</b></myTag>由以上例子我么可以看出,可以直接通过点属性的方法来获取 Tag,但是这种方法只能获取第一个标签 。同时我们可以多次调用点属性这个方法,来获取更深层次的标签 。
# demo 3soup = BeautifulSoup(html_doc, "lxml");print(soup.p.b)#输出结果<b>首页</b>如果想获得所有的某个名字的标签,则可以使用 find_all(tag_name) 函数 。
# demo 4soup = BeautifulSoup(html_doc, "lxml");a_tags=soup.find_all("a")print(a_tags)#输出结果[<a class="website" href=https://www.isolves.com/it/cxkf/yy/Python/2022-07-04/"https://www.google.com" id="google">Google, Baidu, Bing]我们可以使用 .contents 将 tag 以列表方式输出,即将 tag 的子节点格式化为列表,这很有用,意味着可以通过下标进行访问指定节点 。同时我们还可以通过 .children 生成器对节点的子节点进行遍历 。
# demo 5soup = BeautifulSoup(html_doc, "lxml");head_tag=soup.headprint(head_tag)print(head_tag.contents)for child in head_tag.children: print("child is : ", child)#输出结果<head><title>index</title></head>[<title>index</title>]child is :<title>index</title>


推荐阅读