from bs4 import BeautifulSoup
import cssselect
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<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>
"""
# <p class="title" name="dormouse"><b>The Dormouse's story</b></p>
# soup = BeautifulSoup(html, "html.parser")
# soup = BeautifulSoup(html, "xml")
soup = BeautifulSoup(html, "lxml")
# soup = BeautifulSoup(html, "html5lib")
'''
四种HTML、XML解析器:html.parser, lxml, xml, html5lib
'''
# 选择元素
print(soup.title)
print(soup.head)
'''
以上都属于bs4.element.Tag
当存在多个节点符合条件时,只会返回第一个符合条件的节点
'''
print(type(soup.title))
# 提取节点信息
# name 提取节点名称
print(soup.title.name)
# string提取节点内容
print(soup.title.string)
# attrs提取节点属性
print(soup.p.attrs)
'''
attrs返回的结果是字典形式
可以通过 soup.p.attrs['name']获取name属性值
也可以不写attrs,直接soup.p['name']获取name属性值
'''
# 嵌套选择
print(soup.title.string)
print("-"*20, 'result', "-"*20)
# 关联选择
# contents选择直属子节点
print(soup.p.contents)
'''
也可以通过一下方法获取直属子节点
for i, child in enumerate(soup.p.children):
print(i, child)
# enumerate 生成一个生成器
'''
# 获取子孙节点
print(soup.p.descendants)
for i, child in enumerate(soup.p.descendants):
print(i, child)
print("-"*20, 'result', "-"*20)
# 获取父节点
print(soup.p.parent)
'''
parent仅匹配最近的直系父节点元素
'''
print("-"*20, 'result', "-"*20)
# 获取所有的祖先节点
print(soup.p.parents)
for i, child in enumerate(soup.p.parents):
print(i, child)
print("-"*20, 'result', "-"*20)
# 获取兄弟节点
print(soup.a.next_sibling)
print(list(enumerate(soup.a.next_siblings)))
print(soup.a.previous_sibling)
print(list(enumerate(soup.a.previous_siblings)))
'''
next_sibling获取节点的下一个兄弟元素
next_siblings获取节点的下面的所有兄弟元素
previous_sibling获取节点的上一个兄弟元素
previous_siblings获取节点的上面所有的兄弟元素
'''
print("-"*20, 'result', "-"*20)
# prettify()按照标准的缩进格式输出
new_html = soup.prettify()
# print(new_html)
print("-"*20, 'result', "-"*20)
# BeautifulSoup方法选择器
# find_all(name, attrs, recursive, text, **kwargs) 查询所有符合条件的元素
'''
name根据元素节点名来查询
attrs根据元素节点属性来查询 attrs参数类型必须是字典类型
也可以不用attrs传递属性,直接使用属性名=属性值进行传递
text 根据文本内容进行匹配,可以传入字符串或者是正则表达式对象
'''
html = """
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<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">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
"""
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(name="ul"))
print(soup.find_all(name="ul", attrs={'id': 'list-2'}))
print(soup.find_all(name="ul", id='list-2'))
'''
如果是不用attrs而是直接使用属性名进行属性查询时,class要用class_,以免和python内置标识符发生冲突
'''
print(soup.find_all(name="li", attrs={'class': 'element'}, text="Foo"))
# find(name, attrs, recursive, text, **kwargs) 查询符合条件的第一个元素
'''
其他查询方法:
find_parent()返回直接父节点
find_parents()返回所有的祖先节点
find_next_sibling()返回后面第一个兄弟节点
find_next_siblings()返回后面所有的兄弟节点
find_previous_sibling()返回前面第一个兄弟节点
find_previous_siblings()返回前面所有的兄弟节点
find_next()返回节点后第一个符合条件的节点
find_all_next()返回节点后所有符合条件的节点
find_previous()返回节点前第一个符合条件的节点
find_all_previous()返回节点前所有符合条件的节点
'''
# css选择器
html = """
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<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">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
"""
soup = BeautifulSoup(html, 'lxml')
print(soup.select("#list-2 .element"))
# attrs获取属性
print(soup.select("#list-2")[0].attrs['class'])
# string、get_text()获取标签内容
print(soup.select("#list-2 .element")[0].string)
print(soup.select("#list-2 .element")[0].get_text())
python库的解析--BeautifulSoup(bs4库)
最新推荐文章于 2023-08-19 09:11:50 发布