本文共 2435 字,大约阅读时间需要 8 分钟。
BeautifulSoup是灵活又方便的网页解析库,处理高效,支持多种解析器。虽然正则表达式比较强大,但是能用“美味的汤”能更加方便实现网页信息的提取就优先使用吧。
官方文档:pip3 install beautifulsoup4
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, "html.parser") | Python的内置标准库,执行速度适中,文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快 文档容错能力强 | 需要安装C语言库 |
lxml XML 解析器 | BeautifulSoup(markup, ["lxml", "xml"]) | 速度快 唯一支持XML的解析器 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性 以浏览器的方式解析文档 生成HTML5格式的文档 | 速度慢 不依赖外部扩展 |
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag
, NavigableString
, BeautifulSoup
, Comment
.
Tag
有两个主要属性:name和attributes soup = BeautifulSoup('Extremely bold')tag = soup.btype(tag)# nametag.name# attributestag.attrstag.attrs['class']tags['class']
在学习find_all()
之前需要了解过滤器。
过滤器贯穿整个搜索的API.过滤器可以被用在tag的name中,节点的属性中,字符串中或他们的混合中,如下:
字符串:传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容# 寻找所有标签soup.find_all('b')
正则表达式:Beautiful Soup会通过正则表达式的 match() 来匹配内容
#找出所有以h开头的标签import refor tag in soup.find_all(re.compile("^h")): print(tag.name)html, head
列表:将与列表中任一元素匹配的内容返回
# 或soup.find_all(["a", "b"])
True: 所有标签
自定义方法:太高级,目前搞不定# 过滤出前后都有文字的标签def surrounded_by_strings(tag): return (isinstance(tag.next_element, NavigableString) and isinstance(tag.previous_element, NavigableString))# 包含 class 属性却不包含 id 属性def has_class_but_no_id(tag): return tag.has_attr('class') and not tag.has_attr('id')
find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件.(BeautifulSoup是最顶的tag)
find_all( name , attrs , recursive , string , **kwargs )
name参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉
soup.find_all('body')
注: 搜索 name 参数的值可以使任一类型的过滤器 ,字符串,正则表达式,列表,方法或是 True .
keyword参数: 如果一个指定名字的参数不是搜索<u>内置的参数名</u>,搜索时会把该参数当作指定名字tag的属性来搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索
for tag in soup.find_all(id=re.compile("^note-\d+")): print(tag.name)
注:搜索指定名字的属性时可以使用的参数值包括字符串,正则表达式,列表, True.对于CSS样式,class因为和内部冲突,所以需要改为class_
string参数:通过 string 参数可以搜搜文档中的字符串内容.与 name 参数的可选值一样, string 参数接受 字符串 , 正则表达式 , 列表, True .
print(soup.find_all(string="诗"))
recursive参数,默认搜索当前节点的所有子孙节点,如果只需要搜索直接节点,则recursive=False
PS: 由于find_all太常用,所以BeautifulSoup
对象和 tag
对象可以被当作一个方法来使用,这个方法的执行结果与调用这个对象的 find_all()
方法
soup.title.find_all(string=True)soup.title(string=True)
find_all还有其他类似方法,详见官方文档,不多说。CSS选择器不太熟悉,所以不去涉及select()
方法。
get_text()
转载地址:http://zyjaa.baihongyu.com/