1、快速开始
(1)使用BeautifulSoup解析代码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出 。
from bs4 import BeautifulSoup
soup=BeautifulSoup(html_doc,'html.parser')
print(soup.prettify())
(2)几个简单的浏览结构化数据的方法。
soup.title:<title>标签+其中的内容
soup.title.name:title
soup.title.string:只有<title>标签中的内容
soup.title.parent.name:head
soup.p:输出html代码中第一个标签为<p>及其内容
soup.p['class']:第一个标签<p>自定义的类名
soup.a:
soup.find_all('a'):输出所有<a>标签
soup.find(id="link3"):输出id="link3"所在的标签
(3)从文档中找到所有标签的链接
for link in soup.find_all('a'):
print(link.get('href'))
(4)从文档中获取所有的文字内容
print(soup.get_text())
2、对象的种类(Tag , NavigableString , BeautifulSoup , Comment)
(1)Tag:(与XML或HTML原生文档中的tag相同)操作方法与字典相同,tag中包含的字符串不能编辑,但是可以被替换成其它的字符串,用 replace_with() 方法。
Name
Attributes
多值属性(在Beautiful Soup中多值属性的返回类型是list,如果转换的文档是XML格式,那么tag中不包含多值属性)
(2)可以遍历的字符串(NavigableString)
NavigableString 对象不支持 .contents 或 .string 属性或 find() 方法.
(3)BeautifulSoup(表示的是一个文档的全部内容)
(4)注释及特殊字符(Comment 对象是一个特殊类型的 NavigableString 对象)
3、遍历文档树
(1)子节点
tag的名字
操作文档树最简单的方法就是告诉它你想获取的tag的name;
如果想获取 <head> 标签,soup.body.b可以获取<body>标签中的第一个<b>标签;
通过点取属性的方式只能获得当前名字的第一个tag,如果想要得到所有的<a>标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到 Searching the tree 中描述的方法,比如: find_all();
.contents 和 .children:只包含tag的直接子节点,tag的 .contents 属性可以将tag的子节点以列表的方式输出。BeautifulSoup 对象本身一定会包含子节点,也就是说<html>标签也是 BeautifulSoup 对象的子节点。(字符串没有 .contents 属性,因为字符串没有子节点);
通过tag的 .children 生成器,可以对tag的子节点进行循环;
.descendants:对所有tag的子孙节点进行递归循环 。
(2)父节点(.parent和.parents)
通过 .parent 属性来获取某个元素的父节点。文档的顶层节点,比如<html>的父节点是BeautifulSoup 对象。通过元素的 .parents 属性可以递归得到元素的所有父辈节点。
(3)兄弟结点
.next_sibling 和 .previous_sibling
4、搜索文档树
(1)过滤器
① 字符串(最简单的过滤器):在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容。
soup.find_all('b')//用于查找文档中所有的<b>标签。
② 正则表达式:传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容。
import re
for tag in soup.find_all(re.compile("^b"))://找出所有以b开头的标签
print(tag.name)
for tag in soup.find_all(re.compile("t"))://找出所有名字中包含”t”的标签
③ 列表:传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回
soup.find_all(["a", "b"])//找到文档中所有的<a>标签和<b>标签
④ True :可以匹配任何值,soup.find_all(True)可查找到所有的tag,但是不会返回字符串节点
⑤ 方法:如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False。
(2)find_all()
① name参数:可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉(搜索 name参数的值可以使任一类型的过滤器,字符串,正则表达式,列表,方法或是True)
② keyword参数:指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索。有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性。
soup.find_all(id='link2')
//包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性
soup.find_all(href=re.compile("elsie"))
//传入 href 参数,Beautiful Soup会搜索每个tag的”href”属性。
soup.find_all(href=re.compile("elsie"), id='link1')
//同时过滤多个属性
(3)CSS选择器
在 Tag 或 BeautifulSoup 对象的 .select() 方法中传入字符串参数,,即可使用CSS选择器的语法找到tag。
通过tag标签逐层查找
找到某个tag标签下的直接子标签
找到兄弟节点标签
通过CSS的类名查找:soup.select(".sister")
通过tag的id查找:soup.select("a#link2")
同时用多种CSS选择器查询元素
通过是否存在某个属性来查找
通过属性的值来查找
通过语言设置来查找
返回查找到的元素的第一个
5、输出
(1)格式化输出
prettify() 方法将Beautiful Soup的文档树格式化后以Unicode编码输出,每个XML/HTML标签都独占一行。BeautifulSoup 对象和它的tag节点都可以调用 prettify() 方法。
(2)压缩输出
如果只想得到结果字符串,不重视格式,那么可以对一个 BeautifulSoup 对象或 Tag 对象使用Python的 unicode() 或 str() 方法。str() 方法返回UTF-8编码的字符串。
(2)输出格式
get_text():得到tag中包含的文本内容。