清风阁

“我宁愿因忠诚而被绞死,也不愿为了偷生而背叛。”——普京

学习Python爬虫(六):美味的BeautifulSoup

BeautifulSoup4是一个可以从HTML、XML文件中提取数据的Python第三方库,你可以指定特定的解析器实现遍历、查找和修改网页数据的功能


构造BeautifulSoup对象

要解析一个HTML或XML文档,只要把它传递给BeautifulSoup的构造方法,可以以:1)字符串,2)文件句柄这两种形式进行传递

from bs4 import BeautifulSoup

""" Create a bs4 object by passing a file handle. """
with open('index.html') as fp:
    soup = BeautifulSoup(sp)

""" Create a bs4 object by passing a string. """
soup = BeautifulSoup("<html>data</html>")

BeautifulSoup会把文档转换成Unicode编码,并且HTML实体也都被转换为Unicode字符

这里写图片描述


对象的种类及其属性和方法

Tag(标签)

一个Tag对象对应一个HTML或HTML原生文档中的标签

标签对象通过soup对象.标签名获取

这里写图片描述

如果想获取所有的同名标签,使用soup对象.find_all()方法

Name(标签名)

标签名通过标签对象.name获取

这里写图片描述

Attribute(标签属性)

标签的属性往出现在xx=xx的键值对的键的位置,访问方法和字典相同,即标签名['属性名']

或者使用标签名.attrs直接访问字典

这里写图片描述

Multi-Valued Attributes(多值属性)

Python通过列表处理多值属性

这里写图片描述

需要注意的是,如果某个属性看起来有多个值但是在HTML定义中却不是一个多值属性,就以一个完整字符串形式返回(不是多值属性)

这里写图片描述

将标签转换为字符串时,多值属性会合并为一个值

使用标签名.getattribute_list('属性名')获取属性对应值列表

这里写图片描述

这里写图片描述

对应标签内包含的文本,BeautifulSoup使用Navigable类包装这些文本

使用soup对象.string获取这些文本

这里写图片描述

使用str()方法将NavigableString转换为Unicode字符串

这里写图片描述

使用标签名.string.replace_with()方法替换NavigableString
或者直接用=赋值

这里写图片描述

BeautifulSoup(美味汤对象)

BeautifulSoup对象表示一个文档的全部内容

大部分时候可以把它当成Tag对象,它支持遍历文档树和搜索文档树中描述的大部分方法

因为BeautifulSoup对象并非真正的HTML或XML标签,所以他没有name或attribute属性,但是有时查看它的name属性时很方便的,所以BeautifulSoup对象包含了一个值为'[document]'的特殊属性

这里写图片描述

Comment(注释,以及其它)

在HTML文档中以<!--注释内容-->标注的东西就是注释

它是一类特殊的NavigableString

这里写图片描述


遍历文档树

通俗的讲,遍历文档树的直接效果就是『从文档的一个位置移动到另一个位置』

这里写图片描述

为了简单起见,我们做如下前提假设:

这里写图片描述

标签树的下行遍历

获取子结点列表(返回列表)

使用tag标签名.contents获取子结点列表

这里写图片描述

获取子结点迭代器(一层迭代)

使用tag标签名.children获取子结点迭代器

用来遍历直系单层儿子结点

这里写图片描述

获取后代结点迭代器(深度递归)

使用tag标签名.descendants获取后代结点迭代器

用来遍历子孙后代结点

这里写图片描述

标签树的上行遍历

获取父亲标签

使用tag标签名.parent获取父亲标签

这里写图片描述

获取先辈标签

使用tag.parents获取先辈标签的迭代器

这里写图片描述

soup的父结点为None

soup为最高层结点,没有父亲结点(为None)

这里写图片描述

在遍历时要考虑到这一点

这里写图片描述

以上,如果parent is None,虽然不能打印parent,但是可以打印parent.name

标签树的平行遍历

注意:所有的平行遍历总是发生在同一个父结点下的哥哥兄弟结点之间!

返回上一个兄弟结点

使用tag标签.next_sibling获取按照HTML文本顺序的下一个平行结点标签

返回上一个兄弟结点

使用tag标签.previous_sibling获取按照HTML文本顺序的上一个平行结点标签

返回平行后继结点迭代器

使用`tag标签.next_siblings获取按照HTML文本顺序的所有后续平行结点标签

返回平行前驱结点标签迭代器

使用tag标签.previous_siblings获取按照HTML文本顺序的所有前面平行结点标签

回退和前进

还记得我们构造BeautifulSoup对象时要传入的第二个参数——是一个『解析器』这个解析器的作用就是自外向里逐层打开标签,在对最里层的标签解析完后再从里往外逐层关闭标签

<html><head><title>This is a Title</title></head></html>

一上面的html代码为例就是,解析器首先打开html标签,接着打开head标签,接着打开title标签,接着关闭title标签,接着关闭head标签,最后关闭html标签

BeautifulSoup提供了重现HTML文档被解析的过程的工具

返回元素

下一个元素

使用tag标签.next_element返回下一个被解析的标签

上一个标签

使用tag标签.previous_element返回上一个被解析的标签

返回迭代器

向后解析

使用tag标签.next_elements返回向后解析的迭代器

向前解析

使用tag标签.previous_elements返回向前解析的迭代器


搜索文档树

find_all()方法

find_all(name, attrs, recursive, string, limit, **kwargs)

find_all()方法遍历当前结点的所有孩子结点,找到匹配模式的标签

这里写图片描述

这里写图片描述

还可以根据CSS类名进行搜索,因为class是Python的关键字所以在BeautifulSoup中使用class_代替CSS的类名的关键字,搜索指定类名的标签

和关键字参数一样,class_也支持不同类型的过滤器:包括字符串、正则表达式、函数(定义一个函数,返回boolean类型,作为参数传给find_all()方法)或者True(所有不是字符串的东西)

将BS对象或Tag对象当成find_all()方法使用

由于find_all()是在是太常用的搜索方法,BeautifulSoup为我们提供了find_all()的简写形式:

>>> soup.find_all('p')
>>> soup('p')
>>> tag.find_all('a')
>>> tag('a')

上面两种写法前者与后者是等价的(后者是前面的语法糖)相当于为BS对象和Tag对象实现了__call__()方法

另外说明,find_all()方法看似返回一个列表

甚至可以对它的返回值进行列表的分片操作

这里写图片描述

但是在查看type(..)类型后发现,其实它是一个bs4.element.ResultSet对象才对

这里写图片描述

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/abc_12366/article/details/79948021
文章标签: Pyhton BeautifulSoup
个人分类: Python语言
上一篇Java:Comparable接口、Comparator接口
下一篇使用Python模块:json模块
想对作者说点什么? 我来说一句

python爬虫-beautifulsoup.ipynb

2018年05月22日 38KB 下载

beautifulsoup python

2013年06月07日 137KB 下载

没有更多推荐了,返回首页

关闭
关闭