数据蛙数据分析每周作业Python

BeautifulSoup基本使用

2019-03-17  本文已影响5人  圆圆KK

BeautifulSoup官方文档介绍:BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库。使用BeautifulSoup更多方便,避免使用正则表达式容易出错,提高效率。

1.解析器

BeautifulSoup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是 lxml。以下为BeautifulSoup官方文档对支持的解析器优缺点对比。

解析器 使用方法 优势 劣势
Python标准库 BeautifulSoup(markup, "html.parser") Python的内置标准库、执行速度适中 、文档容错能力强 Python 2.7.3 or 3.2.2)前的版本中文容错能力差
LXML HTML 解析器 BeautifulSoup(markup, "lxml") 速度快、文档容错能力强 需要安装C语言库
LXML XML 解析器 BeautifulSoup(markup, "xml") 速度快、唯一支持XML的解析器 需要安装C语言库
html5lib BeautifulSoup(markup, "html5lib") 最好的容错性、以浏览器的方式解析文档、生成 HTML5 格式的文档 速度慢、不依赖外部扩展

推荐使用lxml解释器,效率更高。注意:不同的解析器返回不同的结果

2.基本使用

通过解析器,BeautifulSoup可以传入一段字符串或文件。

from bs4 import BeautifulSoup
>>> soup = BeautifulSoup("<html>data</html>")
>>> print(soup.html.string)
data

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment。接下来使用以下文档进行说明。

html_doc = """
<html><head><title>The Dormouse's story</title></head>

<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">...</p>
"""
soup = BeautifulSoup(html_doc, 'lxml')
print(soup.prettify())
>>> soup.head 
<head><title>The Dormouse's story</title></head>
>>> soup.body.b
<b>The Dormouse's story</b>
>>> soup.a
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

可以看到a点只是返回第一个,如果需要历遍全部则需要用find_all('a')。
tag有多种属性,其中两个最重要的就是name和attributes。name一般返回标签本身(soup返回document),注意,tag属性操作方法和字典一样。

>>> soup.name 
'[document]' #soup比较特殊,返回name为[doucument]
>>> soup.p.name
p 
>>> soup.p.attrs
{'class': ['title']}
>>> soup.p['class'] #可以直接修改属性soup.p['class'] = 'a'
['title']
>>> soup.p.string
"The Dormouse's story"
>>> soup.p.string.replace_with("no")
>>> soup.p.string
'no'
>>> markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
>>> soup = BeautifulSoup(markup)
>>> soup.b.string
'Hey, buddy. Want to buy a used parser?'
>>> type(soup.b.string)
bs4.element.Comment
3.节点选择

上面说到节点选择可以直接利用标签,如<head>标签用soup.head,也可通过name和attrs可以直接获取属性,操作和字典一样。以上是直接获取的方式,当想要获取标签的子节点、父节点、兄弟节点则需要通过另外的方法。

选择 方法
直接节点 .contents和.children(生成器)
子孙节点 .descendants(生成器)
节点内容 .strings和.stripped_strings(去除空格和空行)
父节点 .parent和.parents(到根节点)
兄弟节点 .next_element(s) 和 .previous_element(s)
>>> len(soup.head.contents)
1 
>>> soup.head.contents
[<title>The Dormouse's story</title>]
>>> soup.head.contents[0]
<title>The Dormouse's story</title>

.children是一个llist生成器,可以对子节点进行历遍循环

>>> soup.body.children
<list_iterator at 0x19e8183a860>
>>> for child in soup.body.children:
>>>    print(child)

.descendants是返回所有子孙节点,比较children和descendants的输出区别

>>> len(list(soup.body.descendants))
19
>>> len(list(soup.body.children))
6
>>> for child in soup.body.descendants:
>>>    print(child)
>>> for string in soup.stripped_strings:
>>>    print(string)
>>> soup.a.parent.name
'p'
>>> for parent in soup.a.parents:
>>>    if parent is None:
>>>        print(parent)
>>>    else:
>>>        print(parent.name)
p
body
html
[document]
4.搜索文档树

find_all( name , attrs , recursive , text , **kwargs )

>>> soup.find_all('a', id="link2")
>>> soup.find_all(['a','b'])
上一篇 下一篇

猜你喜欢

热点阅读