BeautifulSoup4是爬虫必学的技能。BeautifulSoup最主要的功能是从网页抓取数据,Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。BeautifulSoup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐使用lxml 解析器。
灵活又方便的网页解析库,处理高效,支持多种解析器。
利用它不用编写正则表达式即可方便地实现网页信息的提取。
安装:pip3 install BeautifulSoup4
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, “html.parser”) | Python的内置标准库、执行速度适中 、文档容错能力强 | Python 2.7.3 or 3.2.2)前的版本中文容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, “lxml”) | 速度快、文档容错能力强 | 需要安装C语言库 |
lxml XML 解析器 | BeautifulSoup(markup, “xml”) | 速度快、唯一支持XML的解析器 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup, “html5lib”) | 最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档 | 速度慢、不依赖外部扩展 |
#基本用法
from bs4 import BeautifulSoup
bs = BeautifulSoup(html,"html.parser") # 缩进格式
print(bs.prettify())
print(bs.prettify()) # 格式化html结构
print(bs.title) # 获取title标签的名称
print(bs.title.name) # 获取title的name
print(bs.title.string) # 获取head标签的所有内容
print(bs.head)
print(bs.div) # 获取第一个div标签中的所有内容
print(bs.div["id"]) # 获取第一个div标签的id的值
print(bs.a)
print(bs.find_all("a")) # 获取所有的a标签
print(bs.find(id="u1")) # 获取id="u1"
for item in bs.find_all("a"):
print(item.get("href")) # 获取所有的a标签,并遍历打印a标签中的href的值
for item in bs.find_all("a"):
print(item.get_text())
#选择元素
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print(soup.head)
print(soup.p)
#获取名称
print(soup.title.name)
print(soup.p.attrs['name'])
print(soup.p['name'])
#获取内容
print(soup.p.string)
#获取子孙节点
print(soup.p.children)
for i, child in enumerate(soup.p.children):
print(i, child)
3.find_all( name , attrs , recursive , text , **kwargs )
可根据标签名、属性、内容查找文档,返回所有符合条件的内容
#通过标签
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all('ul'))
print(type(soup.find_all('ul')[0]))
#通过属性
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'))
#通过text
print(soup.find_all(text='Foo'))
4.find( name , attrs , recursive , text , **kwargs )
find返回单个元素,find_all返回所有元素
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find('ul'))
print(type(soup.find('ul')))
print(soup.find('page'))
find_parents() find_parent()
find_parents()返回所有祖先节点,find_parent()返回直接父节点。
find_next_siblings() find_next_sibling()
find_next_siblings()返回后面所有兄弟节点,find_next_sibling()返回后面第一个兄弟节点。
find_previous_siblings() find_previous_sibling()
find_previous_siblings()返回前面所有兄弟节点,find_previous_sibling()返回前面第一个兄弟节点。
find_all_next() find_next()
find_all_next()返回节点后所有符合条件的节点, find_next()返回第一个符合条件的节点
find_all_previous() 和 find_previous()
find_all_previous()返回节点后所有符合条件的节点, find_previous()返回第一个符合条件的节点
5.css选择
通过select()直接传入CSS选择器即可完成选择
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0]))
for ul in soup.select('ul'):
print(ul.select('li'))
#获得属性
for ul in soup.select('ul'):
print(ul['id'])
print(ul.attrs['id'])
#获取内容
for li in soup.select('li'):
print(li.get_text())
BeautifulSoup4将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
1.Tag
我们可以利用 soup 加标签名轻松地获取这些标签的内容,这些对象的类型是bs4.element.Tag。但是注意,它查找的是在所有内容中的第一个符合要求的标签。
print(type(bs.a))
对于 Tag,它有两个重要的属性,是 name 和 attrs:
2.NavigableString
既然我们已经得到了标签的内容,那么问题来了,我们要想获取标签内部的文字怎么办呢?很简单,用 .string 即可
print(type(bs.title.string))
3.BeautifulSoup
BeautifulSoup对象表示的是一个文档的内容。大部分时候,可以把它当作 Tag 对象,是一个特殊的 Tag,我们可以分别获取它的类型,名称,以及属性
4.Comment
Comment 对象是一个特殊类型的 NavigableString 对象,其输出的内容不包括注释符号。
1、.contents:获取Tag的所有子节点,返回一个list
# tag的.content 属性可以将tag的子节点以列表的方式输出
print(bs.head.contents)
# 用列表索引来获取它的某一个元素
print(bs.head.contents[1])
2、.children:获取Tag的所有子节点,返回一个生成器
for child in bs.body.children:
print(child)
3.descendants:获取Tag的所有子孙节点
4、.strings:如果Tag包含多个字符串,即在子孙节点中有内容,可以用此获取,而后进行遍历
5、.stripped_strings:与strings用法一致,只不过可以去除掉那些多余的空白内容
6、.parent:获取Tag的父节点
7、.parents:递归得到父辈元素的所有节点,返回一个生成器
8、.previous_sibling:获取当前Tag的上一个节点,属性通常是字符串或空白,真实结果是当前标签与上一个标签之间的顿号和换行符
9、.next_sibling:获取当前Tag的下一个节点,属性通常是字符串或空白,真是结果是当前标签与下一个标签之间的顿号与换行符
10、.previous_siblings:获取当前Tag的上面所有的兄弟节点,返回一个生成器
11、.next_siblings:获取当前Tag的下面所有的兄弟节点,返回一个生成器
12、.previous_element:获取解析过程中上一个被解析的对象(字符串或tag),可能与previous_sibling相同,但通常是不一样的
13、.next_element:获取解析过程中下一个被解析的对象(字符串或tag),可能与next_sibling相同,但通常是不一样的
14、.previous_elements:返回一个生成器,可以向前访问文档的解析内容
15、.next_elements:返回一个生成器,可以向后访问文档的解析内容
16、.has_attr:判断Tag是否包含属性