BeautifulSoup是一个html文档解析库,在爬虫解析数据时,十分有用。接下来记录下它的用法。
file = open("./Test.html",encoding="utf-8")
soup = BeautifulSoup(file,"html.parser")
content = '''
百度一下,你就知道
'''
soup = BeautifulSoup(content,"html.parser")
这种比较常用,不过实际使用时,content会替换为网页实时抓取到的文本内容。
接下来我们就以上面这段文本作为数据源来说明,下面的所有方法都基于这段文本的解析
我们刚刚创建出来的soup对象,即是BeautifulSoup类型。可以打印一下
print(type(soup))
输出:<class 'bs4.BeautifulSoup'>
Tag类型是一个很重要的类型,那什么是Tag呢,就是类似于xml里一个标签,如下图
<div id="u1">
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 a>
div>
Tag可分为name,attrs,string 三部分。结构如图
#获得找到的第一个名字为a的标签
print(soup.a)
#结果: 新闻
#打印名字
print(soup.a.name)
#结果:a
#打印属性
print(soup.a.attrs)
#结果:{'class': ['mnav'], 'href': 'http://news.baidu.com', 'name': 'tj_trnews'}
#打印内容
print(soup.a.string)
#结果:新闻
这两个其实都是Tag的string内容。区别点在于,如果内容全注释着,就是Comment类型;否则就是NavigableString类型
<title attr1="val1" attr2="val2">百度一下,你就知道 title>
<ha attr1="val1" attr2="val2">ha>
print(type(soup.title.string))
#结果:
print(type(soup.ha.string))
#结果:
print(soup.title.string)
#结果:百度一下,你就知道
print(soup.ha.string)
#结果:我是注释里的内容
#注意上面这里直接获得了注释里的内容
我们可以用根据标签的名字来获得标签。
for item in soup.head.contents:
print(item.name)
'''
结果:
None
meta
None
meta
None
meta
None
link
None
title
None
ha
None
'''
可以看到子标签都打印出来了(其中会夹着一些none节点)
前面的content和children获取到的直属子节点,不能获得孙子节点。而descendants可以获取到所有子节点
for item in soup.body.descendants:
print(item.name)
next_sibling 下一个弟节点
next_siblings 位于自己下面的所有弟节点
previous_sibling 上一个兄节点
previous_siblings 位于自己上面的兄节点
不同于兄弟节点的遍历,这里的前后遍历可以达到子节点。从根节点往后遍历,可以到达所有节点.
#查找 name=“a” 的所有标签
alla = soup.find_all(name="a")
for a in alla:
print(a)
结果
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 a>
上面也可以写成soup.find_all("a”),不指定关键字默认是以name来作为条件
allItem = soup.find_all(text="新闻 ")
for item in allItem:
print(item)
结果
新闻
注意这里找出来的都是string,不是Tag
除了name,text,attrs等关键词外,其他的代表属性。比如
allItem = soup.find_all(href="//www.baidu.com/more/")
for item in allItem:
print(item)
结果
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 </a>
如果属性和python关键字重合,比如class,需要加下划线_,比如
allItem = soup.find_all(class_="mnav")
for item in allItem:
print(item)
结果
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 a>
可以加多个条件,比如
allItem = soup.find_all(class_="mnav",href="http://news.baidu.com",name="a")
for item in allItem:
print(item)
结果
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 a>
list = {"mnav","bri"}
allItem = soup.find_all(class_=list)
for item in allItem:
print(item)
结果
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 a>
allItem = soup.find_all(href =re.compile("www."))
for item in allItem:
print(item)
结果
<link href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css"/>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 </a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 </a>
指定方法,可以传入一个方法作为参数,但这个方法需要带Tag作为参数。比如:
def has_attr_name(tag):
return tag.has_attr('name')
allItem = soup.find_all(has_attr_name)
for item in allItem:
print(item)
结果
<meta content="always" name="referrer"/>
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻 a>
<a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123 a>
<a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图 a>
<a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频 a>
<a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧 a>
<a class="bri" href="//www.baidu.com/more/" name="tj_briicon"> 更多产品 a>
BeautifulSoup还可以用search()来搜索,不过由于自己刚使用BeautifulSoup不久,目前多以find_all()来完成搜索,这个不太熟. 就不写了…