Beautifulsoup
网页解析库,灵活方便,处理效率高,支持多种解析器
利用它不用编写正则表达式,即可实现网页信息的处理
需定义frombs4 import Beautifulsoup
1. 用法详解
BeautifulSoup解析库
解析器 | 使用方法 | 优势 | 备注 |
Python标准库 | BeautifulSoup(markup,'html.parnser') | python内置标准库,速度适中,文档容错强 | python2.7.3 or 3.2.2 中文容错差 |
lxml HTML解析器 | BeautifulSoup(markup,'lxml') | 速度快,文档容错能力强 | 需要安装C语言库 |
lxml XML解析器 | BeautifulSoup(markup,'xml') | 速度快,唯一支持xml的解析器 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup,'html5lib') | 容错最好,以浏览器的方式解析,生成html5格式的文档 | 速度慢,不依赖外部扩展 |
2. 基本使用方法
from bs4 importBeautifulSoup
html = '''
<html><head><title>TheTom Story</title></head>
<pname='dromouse'><b>The Dormouse's story</b></p>
<pclass='story'>Once upon a time there were three little sisters; and theirnames were
<a href='http://example.com/elsie'id='link1'><!--Elsle--></b>,
<a href='http://example.com/lacie'class='sister' id='link2'>Lacie</a> and
<a href='http://example.com/title'class='sister' id='link3'>Title</a>;
and they lived at the bottom of awell.</p>
<p>...</p> #去掉通过Beautifulsoup自动补全
'''
soup=BeautifulSoup(html,'lxml')
print(soup.prettify())
#转变为html的标准格式,例如‘’转为"",标签自动闭合
3. 标签选择器
1>
print(soup.title) #打印标签,代替正则
#返回 <title>The Tom Story</title>
print(soup.head)
#返回 <head><title>The Tom Story</title></head>
print(soup.p) #<p>标签多个,只返回第一个
2>
print(soup.title.name) #标签名称 返回title
print(soup.title.string) #标签中内容 返回The Tom Story
print(soup.head.title.string) #用‘.’分隔,进行嵌套选择
print(soup.p.string) #第一个p标签内容 à TheDormouse's story
3>
print(soup.p.attrs['name']) #获取属性的值
print(soup.p['name']) #两者返回结果相同 为dromouse
print(soup.p.attrs['class'])
print(soup.p['class'])
#返回 ['title']此列表类型与class关键字有关,若换做其他,则返回字符串
4>
html = '''
<html>
<head>
<title>
The Tom Story
</title>
</head>
<body>
<p>
Once upon a time there werethree little sisters; and their names were
<ahref="http://example.com/elsie" id="link1">
<span><!--Elsle--></span>
</a>
<ahref="http://example.com/lacie"id="link2">Lacie</a>
and
<ahref="http://example.com/title"id="link3">Title</a>
and they lived at the bottom ofa well.
</p>
<p>...</p>
</body>
</html>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.p.contents) #contents用来选择子节点(下一级),返回列表
print(soup.p.children) #同contents一样,返回列表,但需要for循环遍历取出
#但不仅限于标签,空格、换行、字符串都包括在内
for i,child inenumerate(soup.p.children):
print(i,child)
# print(soup.p.descendants) #descendants 所有子孙节点
for i,child inenumerate(soup.p.descendants):
print(i,child) #返回第一个p标签下的所有内容
print(soup.a.parent) #父节点,返回上一级,即p节点下的所有内容原型输出
print(list(enumerate(soup.a.parents)))
#parents祖父节点,顺序往上一级父节点,再上一级,最后输出整个html
print(list(enumerate(soup.a.next_siblings))) #兄弟节点
#打印第一个a标签后的所有同级的内容,不包括本身
print(list(enumerate(soup.a.previous_siblings)))
#第一个a标签前的同级内容,不包括本身
#小结:它是一种标签选择器,基于C库,速度非常快,但是在实际使用中并不能满足我们的需求,比如一些class属性
4. 标准选择器
find_all(name,attrs,recursive,text,**kwargs),类似正则的findall, 可根据标签名,属性,内容查找文档找出所有的相关内容
html='''
<div>
<div>
<h4>Hello</h4>
</div>
<div>
<ul id="list-1">
<li>Foo</li>
<li>Bar</li>
<li>Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<liclass="element">Foo</li>
<li>Bar</li>
</ul>
</div>
</div>'''
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.find_all('ul')) #打印所有ul标签
for ul in soup.find_all('ul'):
for li in ul.find_all('li'):
print(li) #根据标签名层层查找迭代,打印所有li标签
#attrs用法,优点在于可以使用字典类型进行查找, 字典的键名,就是html标签中属性的名称, 键值就是对应标签中属性的值
print(soup.find_all(attrs={'id':'list-1'})) #定位到该内容,并以列表形式输出完整标签
print(soup.find_all(attrs={'name':'elements'})) #结果同上
#另一种写法
print(soup.find_all(id='list-1'))
print(soup.find_all(class_='element'))
#class是python的保留字,所以在这里我们为了让程序加以区分, 写成 class_
# text的相关用法 即根据文本的内容进行选择
print(soup.find_all(text='Foo')) #返回 ['Foo', 'Foo']
5. find ,与find_all不同, find用来返回单个元素
html = '''
<div>
<div>
<h4>Hello</h4>
</div>
<div>
<ul id="list-1">
<liclass="element">Foo</li>
<liclass="element">Bar</li>
<liclass="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<liclass="element">Foo</li>
<liclass="element">Bar</li>
</ul>
</div>
</div>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.find('ul')) #返回第一个ul标签
#find_parents() #返回所有祖先节点,用法同上
#find_parent() #返回直接父节点,用法同上
#find_next_siblings() #返回后面所有兄弟节点
#find_next_sibling() #返回后面第一个兄弟节点
#find_previous_siblings() #返回前面所有兄弟节点
#find_previous_sibling() #返回前面第一个兄弟节点
#find_all_next() #返回节点后所有符合条件的节点
#find_next() #返回节点后第一个符合条件的节点
#find_all_previous() #返回节点前所有符合条件的节点
#find_all_previou() #返回节点前第一个符合条件的节点
6. CSS 选择器
通过select()直接传入CSS选择器即可完成选择
1>
html='''
<div>
<div>
<h4>Hello</h4>
</div>
<div>
<ul id="list-1"name="elements">
<li>Foo</li>
<li>Bar</li>
<li>Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li>Foo</li>
<li>Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.select('.panel .panel-heading'))
#节点在class里,则前面要加一个‘.’,返回该内容所处位置标签的整个内容
print(soup.select('ul li'))
#根据标签,找到ul中的li标签,并返回所有li标签
print(soup.select('#list-2 .element'))
#节点在id里,前面要加一个#,返回了在节点id=list-2下,且内容有class=element的两个li标签的内容
for ul in soup.select('ul'):
print(ul.select('li'))
2>
Select获取属性值的方法
for ul insoup.select('ul):
print(ul['id']) #用来获取id里面的值
print(ul.attrs['id']) #同上
3>
获取内容的方法
for li insoup.select('li):
print(li.get_text()) #打印li标签里面的内容
#返回Foo Bar Jay Foo Bar