获取网页是一长串的 html 代码,并不是我们想要的数据解析网页
安装BeautifulSoup4
pi3 install bs4
1.导入bs4库
from bs4 import BeautifulSoup
2.创建beautifulsoup对象
先创建一个demo网页
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
<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>
</body>
</html>
"""
创建一个beautifulsoup对象
soup = BeautifulSoup(html)
或者通过读取本地HTML文件创建对象
soup = BeautifulSoup(open('demo.html'))
3.bs4将html文档转换成一个树形结构,每个节点都是 Python 对象,所有对象可以归纳为4种:
Tag
NavigableString
BeautifulSoup
Comment
1.tag
<title>The Dormouse's story</title>
<b>The Dormouse's story</b>
<p class="story">Once upon a time there were three little sisters; </p>
上面的title、b、p 等 HTML 标签加上中间的内容就是一个 Tag,我们来试试如何通过 beautifulsoup 进行 Tag 内容获取
print(soup.title)
输出:The Dormouse’s story
print(soup.head)
输出:The Dormouse’s story
print(soup.p)
输出:The Dormouse’s story
通过标签名只能查找到所有内容中第一个符合要求的标签
每个 tag 都有自己的 name,一个 tag 也会有多个属性 attrs 。tag 属性的操作方法和字典相同
print(soup.title.name)
输出:title
print(soup.p.attrs)
输出 {‘class’: [‘title’], ‘name’:‘dromouse’}
通过字典方式获取其中某一个属性
两种方式都可
print(soup.p.get(‘class’))
print(soup.p[‘class’])
2.NavigableString
可以遍历的字符串
既然已经通过 Tag 获取到具体标签,那标签的内容就可以通过 NavigableString 拿到,使用方法特别简单:
# 获取标签内容
print(soup.p.string)
BeautifulSoup 对象表示的是一个文档的全部内容。大部分时候,可以把它当作是一个特殊的 Tag,我们可以分别获取它的名称、属性
print(soup.name)
print(soup.attrs)
4.comment
Comment 对象是一个特殊类型的 NavigableString 对象,输出的内容不包括注释符号
print(soup.a)
print(soup.a.string)
a 标签的内容实际上属于注释,利用 .string 来输出它的内容,我们发现它已经把注释符号去掉了。
实际上a 标签的内容属于注释,即 Comment。可以这样操作:
from bs4 import Comment
if type(soup.a.string) == Comment:
print(“comment:”+soup.a.string)
find_all
所有节点
find_all(name, attrs, recursive, text, limit, **kwargs):搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件
find搜索子节点
css选择器
1)通过标签名查找
查找所有找到的结果,返回 list
查找title标签
print(soup.select(‘title’))
查找 a 标签
print(soup.select(‘a’))
(2)通过类名查找
查找 class 是 sister 的所有结果
print(soup.select(’.sister’))
(3)通过 id 名查找
查找 id 为 link1 的所有结果
print(soup.select(’#link1’))
(4)组合查找
查找 p 标签中, id 为 link1 的所有结果
print(soup.select(‘p #link1’))
查找 p 标签中, class 为 sister 的所有结果
print(soup.select(‘p .sister’))
子标签查找
print(soup.select(‘body > p’))
组合查找
body 标签下的 class 为 story 的标签下的 id 为 link1 的所有结果
print(soup.select(‘body .story #link1’))
(5)属性查找
查找时还可以加入属性元素,属性需要用中括号括起来。
注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到。
查找 id 为 link1 的所有结果
print(soup.select(‘a[id=“link1”]’))
查找 p 标签下的 id 为 link2 的 a 标签
print(soup.select(‘p a[id=“link2”]’))
输出 id 为 link 的 a 标签的内容
print(soup.select(‘a[id=“link2”]’)[0].string)
css 选择其实和 find_all 函数的本质是一样的,选择合适的使用吧