简介
Beautiful Soup是一个非常流行 的 Python 模块。该模块可以解析网页,并提供定位内容的便捷接口。并且可以自动修复网页内容。lxml 只会局部遍历,而Beautiful Soup 是基于HTML DOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。支持css选择器。
安装:pip install beautifulsoup4
解析器种类
html补全
使用 Beautiful Soup的第一步是将己下载的HTML内容解析为soup 文档 。
from bs4 import BeautifulSoup
broken_html ='<ul class=country> <li>Area</li> <li>Population</ul>'
soup = BeautifulSoup(broken_html,'html.parser')
fixed_html = soup.prettify() # 也可不加
print(fixed_html) # BeautifulSoup 能够正确解析缺失的引号并闭合标签
beautifulsoup获取数据的三种方法
遍历文档树
################# 遍历文档树
# 节点内容
soup.p.string
# 获取p标签的内容,如果tag只有一个navigablesting类型子节点,那么这个tag可以使用.string得到子节点内容,如果超过一个,返回None
例:<div>div-content<span>span-content</span></div>此标签还有一个span标签也有一个navigablesting类型
# 多个内容
.strings属性,获取所有内容,返回一个generator(包含空白字符)
.stripped_strings属性,获取所有内容,返回一个generator(去除空白字符)
例:
print(list(soup.div.strings))
结果为:['div-content', 'span-content']
# 直接子节点
.contents 将tag的子节点以列表的方式输出,包含当前标签的内容
.children 将tag的子节点以list_iterator的方式输出
例:
soup.div.children # 返回div标签的内容和div标签的子标签
soup.div.contents
# 所有子孙节点
.descendants属性 对所有子节点递归
例:
soup.div.descendants # 返回div标签的内容和div标签的子标签和子标签的内容
# 父节点
.parent 获取父节点
# 全部父节点
.parents 获取全部父节点
# 兄弟节点 ----换行也算一个兄弟节点
.next_sibling 下一个兄弟节点
.previous_sibling 下一个兄弟节点
例:
repr(soup.p.next_sibling)
# 全部兄弟节点 ----换行也算一个兄弟节点
.next_siblings 下一个兄弟节点
.previous_siblings 下一个兄弟节点
# 前后节点 ----换行也算一个节点,当前tag的navagablestring也算一个节点
.next_element 后一节点
.previous_element 前一节点 知道html标签
例:
soup.p.next_element.next_element
# 所有前后节点
.next_elements 所有后节点
.previous_elements 所有前节点
搜索文档树
################# 搜索文档树
# 通过标签查找
soup.find_all(['p', 'div']) # 查找p和div标签
soup.find_all('p', limit=3) # 查找前三个p标签,返回标签
# 通过属性查找
soup.find_all(id='panda') # 查找id为panda的标签,返回此标签全部内容例:<div id='panda'>内容</div>
tr = soup.find(attrs={'id': 'places_area__row'})
td = tr.find(attrs={'class': 'w2p_fw'})
# 通过正则配合内容查找
soup.find_all(text=re.compile('content$')) # 查找标签内容以content结尾,以列表形式返回标签的文本内容。
css选择器
################### css选择器
# 标签名查找
soup.select('p') # 查找p标签
# 类名查找
soup.select('.p-class') # 查找类名为p-class的标签
# id查找
soup.select('#panda') # 查找id为panda的标签
# 组合查找
soup.select('p #panda') # 查找p标签下id为panda的标签
# 属性查找
soup.select('p[class="p-class"]') # 查找class='p-class'的p标签
element > element div > p 选择所有父级是 div元素的 p元素
element + element div + p 选择所有紧接着div元素之后的p元素
element1 ~ element2 p ~ div 选择p元素之后的每一个ul元素
更多css选择器语法参考:
http://www.runoob.com/cssref/css-selectors.html
获取文本内容和属性
soup = BeautifulSoup(html_doc, 'html.parser')
s = soup.select('p.story') # class为story的p标签,返回为list类型
# 文本内容
s[0].get_text() # p节点及子孙节点的文本内容,或者s[0].text
s[0].get_text("|") # 指定文本内容的分隔符
s[0].get_text("|", strip=True) # 去除文本内容前后的空白
# 属性
print(s[0].get("class")) # p节点的class属性值列表(除class外都是返回字符串)