目录
网页数据解析与爬取----Beautiful Soup
Beautiful Soup 使用
1、Beautiful Soup简介
1、解析工具Beautiful Soup,其借助网页的结构和属性等特性来解析网页
2、Beautiful Soup是Python的一个HTML或XML的解析库,可方便地从网页中提取数据,提供一些简单的、Python式的函数来处理导航、搜索、修改分析树等功能
3、Beautiful Soup自动将输入文档转换为Unicode编码,将输出文档转换为utf-8编码
4、Beautiful Soup可省去很多繁琐的提取工作,提高解析网页效率
2、解析器
Beautiful Soup在解析时是依赖解析器的,除了支持Python标准库中的HTML解析器,还支持一些第三方解析器
Beautiful Soup常用解析器
推荐使用LXML解析器,它有解析HTML和XML的功能,速度快、容错能力强
3、准备工作
1、安装Beautiful Soup库
pip install beautifulsoup4
2、基本使用
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
# 调用prettify方法,这个方法可以把要解析的字符串以标准的缩进格式输出
print(soup.prettify())
# 调用soup.title.string,输出html中title节点的文本内容
print(soup.title.string)
4、节点选择器
说明:直接调用节点的名称即可选择节点,然后调用string属性就可得到节点内的文本,这个方法只会选择到第一个匹配的节点,后面的其他节点都会忽略
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
print(soup.p)
5、提取信息
1、获取名称
说明:利用name属性获取节点的名称
print(soup.title.name) --> title
2、获取属性
一个节点可能有多个属性,例如id和class等,选择这个节点元素后,可调用attrs获取其所有属性
# 调用attrs属性的返回结果是字典形式,包括与哦所有选择节点的所有属性和属性值
print(soup.p.attrs)
print(soup.p.attrs['name'])
# 简写
print(soup.p['name'])
print(soup.p['class'])
3、获取内容
利用string属性获取节点元素包括的文本内容
# 只获取第一个节点
print(soup.p.string)
4、嵌套选择
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)
6、关联选择
在做选择过程中,有时不能一步就选到想要的节点,需要先选中某一个节点,再以它为基准选子节点、父节点、兄弟节点等
1、子节点和子孙节点
选取节点之后,如果想要获取它的直接子节点,可调用contents属性
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.contents) # 返回结果是列表类型
也可调用children属性得到相应的结果
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
# 返回结果是生成器类型
print(soup.p.children)
for i,child in enumerate(soup.p.children):
print(i, child)
如果要得到所有的子孙节点,可调用descendants属性
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
# 返回结果是生成器类型
print(soup.p.descendaants)
for i,child in enumerate(soup.p.descendaants):
print(i, child)
2、父节点和祖先节点
如果要获取某个节点元素的父节点,可调用parent属性
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
# 返回结果是生成器类型
print(soup.a.parent)
如果想获取所有祖先节点,可调用parents属性
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
# 返回结果是生成器类型
print(soup.a.parents)
3、兄弟节点
获取兄弟节点
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
# 获取节点的下一个兄弟节点
print('Next Sibling', soup.a.next_sibling)
# 获取节点的上一个兄弟节点
print('Prev Sibling', soup.a.previous_sibling)
# 返回后面的所有兄弟节点
print('Next Siblings', list(enumerate(soup.a.next_siblings)))
# 返回前面的所有兄弟节点
print('Prev Siblings', list(enumerate(soup.a.previous_siblings)))
7、方法选择器
1、find_all
find_all,查询所有符合条件的元素,可给它传入一些属性或文本来得到符合条件的元素
find_all(name, attrs, recursive, text, **kwargs)
2、name
根据name属性查询元素
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(name='ul'))
print(type(soup.find_all(name='ul')[0]))
3、attrs
根据属性进行查询
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(attrs={'id':'list1'}))
4、text
text参数可以用来匹配节点的文本,其传入形式可以是字符串,也可是正则表达式对象
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(text=re.compile('link')))
5、find
find方法也可查询符合条件的元素,只不过find方法返回的是单个元素,即匹配第一个元素,而find_all会返回由所有匹配的元素组成的列表
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find(name='ul'))
print(soup.find(text=re.compile('link')))
说明:
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_previous:前者返回节点前面所有符合条件的节点,后者返回前面第一个符合条件的节点
8、CSS选择器
只需调用select方法,传入相应的CSS选择器即可
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
1、嵌套选择
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
print(ul.select('li'))
2、获取属性
使用attrs获取属性
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
print(ul['id'])
print(ul.attrs['id'])
3、获取文本
使用string属性获取文本
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for li in soup.select('li):
print('Get text:', li.get_text())
print('String:', li.string)