-
Tag
-
NavigableString
-
BeautifulSoup
-
Comment
解析HTML:
需要一个BeautifulSuop对象,还需要一个解析器解析内容,形成一个树形结构经过赋值的对象来遍历
from bs4 import BeautifulSoup bs=BeautifulSoup(html,"html.parser") #解析内容赋值给对象bs
1.Tag 标签及其内容(默认拿到第一个找到的标签)
(1)print(bs.a) #打印a标签及a标签的子内容(子标签)
类型:bs4.element.Tag
(2)print(bs.a.string) #打印a标签里面的文字内容
类型:bs4.element.NavigableString
(3)print(bs.name) #bs本身的name 即为 [document]
(4)print(bs.head.name) #输出标签本身的名称(没啥用,你都知道名称了还输出个鬼啊,为什么会有这种离谱方法)
2.NavigableString 标签里的内容(字符串)
(1)print(bs.a.attrs) #打印a标签里的属性(输出字典)
(2)print(bs.a['class'])#打印a标签里的class属性,等价bs.a.get('class')
(3)bs.a['class'] = "newClass" #可以对这些属性和内容等等进行修改
print(bs.a)
(4)del bs.a['class'] #还可以对这个属性进行删除
print(bs.a)
3.BeautifulSoup 表示整个文档的内容
BeautifulSoup对象表示的是一个文档的内容。大部分时候,可以把它当作 Tag 对象,是一个特殊的 Tag,我们可以分别获取它的类型,名称,以及属性。
print(type(bs.name))
print(bs.name)
print(bs.attrs)
......
4.Comment 注释
是一个特殊的NavigableString输出的内容不包含注释符号
html的注释格式是“<!- 注释的内容 ->”,该格式在开始标签中有一个惊叹号,但是结束标签中没有;并且在浏览器中是不会显示注释的,但是能够帮助记录HTML文档。
假设a标签有注释
print(bs.a.string) #得到标签里的·文本
print(type(bs.a.string)) #得到<class 'bs4.element.Comment'> (注释类型)
应用
1.文档的遍历
contents:获取标签的所有子节点,返回list
print(bs.head.contents) #打印head标签所有子节点,输出类型:列表
print(bs.head.contents[0]) #打印head标签里第一个元素内容
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 是否包含属性
2.文档的搜索
(1) find_all() 在所有查找
字符串过滤:会查找与字符串完全匹配的内容
list_1=bs.find_all('a') #只查找名为a的标签(在文档所有内容中)
(2)正则表达式搜索:使用search()方法来匹配内容
import re
list_1=bs.find_all(re.compile('a')) #只要标签含a,标签及其子内容都会找出来
(3)传入一个函数(方法)根据函数的要求来搜索
def search(tag):
return tag.has_attr('name')
list_1=bs.find_all(search)
for i in list:
print(i) #输出包含name属性的标签,格式为< />
(4)通过kwargs参数搜索
list_1 = bs.find_all(id="head")
print(t_list) # 拿到id=head的Tag
list_1 = bs.find_all(href=re.compile("http://www.baidu.com"))
print(list_1) # 拿到href属性包含http://www.baidu.com的Tag
list_1 = bs.find_all(class_=True)
print(list_1)
# 拿到所有包含class的Tag(注意:class在Python中属于关键字,所以加_以示区别)
list_1=bs.find_all(class_="a")
print(list_1) #拿到class为a的Tag
(3)attrs参数
并不是所有的属性都可以使用上面这种方式进行搜索,比如HTML的data-*属性
使用attrs参数,定义一个字典来搜索包含特殊属性的tag:
list_1 = bs.find_all(attrs={"data-foo":"value"})
for item in t_list:
print(item)
(4)text参数
通过text参数可以搜索文档中的字符串内容,与name参数的可选值一样,text参数接受 字符串,正则表达式,列表
list_1=bs.find_all(text='hao123') #使用字符串搜索
list_1 = bs.find_all(text=["a", "b", "c"]) #添加多个参数搜索
应用正则表达式来查找包含特定文本的内容
import re
list_1=bs.find_all(text=re.compile('ABC'))
搜索text中的一些特殊属性时,同样也可以传入一个方法来达到我们的目的
(5)limit参数(个数)
使用limit参数限制传出结果的个数
list_1=bs.find_all('a',limit=3) #只能得到3个a标签
(6)find()
find()将返回符合条件的第一个Tag,有时我们只需要或一个Tag时就可以用到find()方法。
当然,也可以使用find_all()方法传入一个limit=1
list_1 = bs.find_all("title",limit=1)
print(t_list) #返回只有一个结果的列表
a = bs.find("title")
print(a) #返回唯一值
b = bs.find("abc")
print(b) #如果没有找到,则返回None
可以通过bs.div来获取第一个div标签,当我们需要获取第一个div下的第一个div时,
我们可以这样:
a = bs.div.div
# 等价于
a = bs.find("div").find("div")
(7)css选择器
list_1=bs.select('title') #通过标签名查找
list_1=bs.select('.mnav') #通过class=类名查找
list_1=bs.select('#u1') #通过id=来查找
list_1=bs.select("a[class='bri']") #通过属性查找
list_1=bs.select('div .bri') #通过组合查找
list_1=bs.select('head>title') #通过子标签来查找
list_1=bs.select('.mave ~ .bri') #查找同级标签