Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
它是一个工具箱,经过解析文档为用户提供须要抓取的数据,由于简单,因此不须要多少代码就能够写出一个完整的应用程序。html
1、安装python
pip install beautifulsoup4
pip install lxml
2、使用正则表达式
from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc,'lxml') res = soup.prettify() # 结构化显示,并补全标签
3、遍历文档树函数
html_doc = """ <html> <head> <title> The Dormouse's story </title> </head> <body> <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 class="sister" href="http://example.com/elsie" id="link1"> Elsie </a> , <a class="sister" href="http://example.com/lacie" id="link2"> Lacie </a> and <a class="sister" href="http://example.com/tillie" id="link3"> Tillie </a> ; and they lived at the bottom of a well. </p> <p class="story"> ... </p> </body> </html> """
from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc,'lxml') print(soup.p) # 找到第一个P标签
print(soup.p.name) # 获取标签的名称 p
print(soup.p.attrs) # 获取标签的属性 {'class': ['title']}
获取标签的文本工具
print(soup.p.text) # 获取p标签下的全部内容
print(soup.p.get_text()) # 获取p标签下的全部内容
print(soup.p.string) # p标签的文本只有一个时,不然返回None
print(soup.p.strings) # 获取生成器对象,取到P标签下的全部内容
for line in soup.p.strings: print(line)
tag对象spa
tag_p = soup.p print(tag_p.attrs) # {'class': ['title'], 'id': 'p1'}
print(tag_p['class']) # ['title']
print(tag_p.get('class')) # ['title']
print(tag_p['id']) # p1
print(tag_p.get('id')) # p1
#一、嵌套选择
print(soup.head.title.string) print(soup.body.a.string) #二、子节点、子孙节点
print(soup.p.contents) #p下全部子节点
print(soup.p.children) #获得一个迭代器,包含p下全部子节点
for i,child in enumerate(soup.p.children): print(i,child) print(soup.p.descendants) #获取子孙节点,p下全部的标签都会选择出来
for i,child in enumerate(soup.p.descendants): print(i,child) #三、父节点、祖先节点
print(soup.a.parent) #获取a标签的父节点
print(soup.a.parents) #找到a标签全部的祖先节点,父亲的父亲,父亲的父亲的父亲...
#四、兄弟节点
print(soup.a.next_sibling) #下一个兄弟
print(soup.a.previous_sibling) #上一个兄弟
print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象
print(soup.a.previous_siblings) #上面的兄弟们=>生成器对象
4、五种过滤器code
html_doc = '''<html><head><title>The Dormouse's story</title></head> <body> <p class="title"><b>The Dormouse's story</b></p> <p class="title"><b>$75</b></p> <p id="meiyuan">啦啦啦啦啦啦</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>'''
from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc,'lxml') # find_all(self, name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)
# 1.字符串,即标签名,特色时彻底匹配
print(soup.find_all('b')) # 找到全部的p标签,返回列表
print(soup.find_all(attrs={'class':"sister"})) # 找到class属性是sister的标签
# 2.正则表达式
import re print(soup.find_all(re.compile('^h'))) # 找到全部h开头的标签,head和html标签
print(soup.find_all(attrs={"id":re.compile("link")})) # 找到id有link的标签
# 3.列表
print(soup.find_all(['a','b'])) # 找到全部的a标签和b标签
# 4.True:能够匹配任何值,下面代码查找到全部的tag,可是不会返回字符串节点
print(soup.find_all(attrs={"id":True})) # 查找全部含有id的标签
print(soup.find_all(name=True)) # 找到全部标签的标签名
# 5.方法:若是没有合适过滤器,那么还能够定义一个方法,方法只接受一个元素参数 ,若是这个方法返回 True 表示当前元素匹配而且被找到,若是不是则反回 False
def has_class_not_id(tag): # 有class属性没id的标签
return tag.has_attr("class") and not tag.has_attr("id") print(soup.find_all(has_class_not_id)) print(soup.find_all(name="a",limit=2))#找全部的a标签,只找前两个
print(soup.body.find_all(attrs={"class":"sister"},recursive=False))#找属性为sister的
print(soup.html.find_all('a')) print(soup.html.find_all('a',recursive=False)) # recursive = True #从子子孙孙都找到了 # recursive = False #若是只想搜索tag的直接子节点(就不往里面找了),可使用参数 recursive=False .
# **kwargs
print(soup.find_all(attrs={"class":"sister"})) print(soup.find_all(class_="sister")) #这两个是同样的
print(soup.find_all(attrs={"id":"link3"})) #这两个是同样的,只是表示方式不同
print(soup.find_all(id="link3"))
find_all() 和 find() 的区别orm
惟一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果.
find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None .xml
find_all( name , attrs , recursive , text , **kwargs )
find( name , attrs , recursive , text , **kwargs )htm
像调用 find_all() 同样调用tag find_all() 几乎是Beautiful Soup中最经常使用的搜索方法,因此咱们定义了它的简写方法. BeautifulSoup 对象和 tag 对象能够被看成一个方法来使用, 这个方法的执行结果与调用这个对象的 find_all() 方法相同,下面两行代码是等价的: soup.find_all("a") soup("a") 这两行代码也是等价的: soup.title.find_all(text=True) soup.title(text=True)
CSS选择器
html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title"> <b>The Dormouse's story</b> Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1"> <span>Elsie</span> </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>; <div class='panel-1'> <ul class='list' id='list-1'> <li class='element'>Foo</li> <li class='element'>Bar</li> <li class='element'>Jay</li> </ul> <ul class='list list-small' id='list-2'> <li class='element'><h1 class='yyyy'>Foo</h1></li> <li class='element xxx'>Bar</li> <li class='element'>Jay</li> </ul> </div> and they lived at the bottom of a well. </p> <p class="story">...</p> """
from bs4 import BeautifulSoup soup=BeautifulSoup(html_doc,'lxml') # 1.经过标签名查找
print(soup.select("title")) # 返回title标签的列表
# 2.经过类名查找
print(soup.select(".sister")) # 3.经过ID查找
print(soup.select("#link1")) # 获取属性
print(soup.select("#list-2")[0].attrs) # {'class': ['list', 'list-small'], 'id': 'list-2'}
# 获取内容
print(soup.select("#list-2")[0].text)