Python爬虫-BeautifulSoup

Python爬虫-BeautifulSoup

“美丽汤”的爱恨

前边说偏爱xpath,在于操作简单,解析速度较快。但不可否认:BeautifulSoup比xpath稳定。但凡网页的标签顺序发生变化(增删改),基于xpath规则的提取方式极大可能就此失效,这样一来不得不“右键检查元素”,周而复始的修改xpath规则。而“美丽汤”提供了多种寻找标签方法,以图使用者达到最佳“确定标签”的目的,尽最大努力在网页发生改变的同时,旧代码仍然畅通无阻的运行。
可是成也萧何败萧何,考虑太多,“美丽汤”不得不显得“臃肿”,成为三个中解析速度中的最慢。然而比起令人生畏的正则,许多人也只好认了:“慢就慢吧”。
《Python网络数据采集》书中提到,BeautifulSoup一名源于《爱丽丝梦游仙境》里的同名诗歌。就突然好想去看,我说有空的话。

使用

关于环境安装的帖子网络上很容易找到,这里不提。

导包:from bs4 import BeautifulSoup
指定解析方式:soup = BeautifulSoup(response.text, "lxml")
或者页面写入本地,打开本地文件解析:soup = BeautifulSoup(open("xxxx"), "lxml")

爱丽丝文档示例

这里写图片描述
在一定的操作中以此范例文档试验(这是一个标签部分残缺的文档


格式化输出:print(soup.prettify())
效果:
这里写图片描述
可以看到,经过处理后,原示例的残缺部分被填充完整。所以我们应该针对处理之后的示例采取相应的提取措施


标签

soup.a返回第一个a标签
这里写图片描述
soup.parent返回a标签的父标签
这里写图片描述
soup.a.parent.name返回a标签的父亲标签的名字
这里写图片描述
soup.a.parents 返回a标签的父级以上标签,类型为迭代器
这里写图片描述
对应parents的是children,用法相同,返回子级标签,注意区别,parents是父级以上,children只有子级
soup.a.attrs返回a标签中的所有属性
这里写图片描述
soup.a.attrs["属性名"] 返回a标签指定属性对应的值
这里写图片描述
soup.title.string返回title标签中的文本信息
soup.head.string返回head标签中的文本信息
这里写图片描述
可以看到,返回结果相同,此方法也能返回注释信息
这里写图片描述
与字符串存在类型区别,但我认为没必要在入门的时候区分这些,以后需要的时候再研究就可以了


遍历

这里写图片描述

下行遍历:
.contents返回一个列表
.children返回一个迭代器
.descendants返回子孙级标签,上面两个只有子级

上行遍历:
.parents

平行遍历:
.next_sibling下一个平行标签
.previous_sibling上一个平行标签
.next_siblings后面所有平行标签,返回类型为迭代器
.previous_siblings前面所有平行标签,返回类型为迭代器


find(),findAll()

find(tag, attrs, recursive, text, keywords)
findAll(tag, attrs, recursive, text, limit, keywords)
区别:除了参数limit外,前者返回第一个符合条件的对象,后者以列表方式返回所有符合条件


——针对tag参数——–
-findAll("a")寻找所有a标签
-findAll({"a", "b", "p"})寻找所有a,b,p标签
——针对attrs参数——-
+findAll("a", {"class":"sister"})寻找标签a且属性class=”sister”
+findAll("a", {"class":{"sister", "brother"})寻找标签a且属性class=”sister”或者brother
+findAll("", {"class":"sister"})不限定标签类型,返回符合属性条件的标签
+以上可以看出,attrs属性不能单独使用
——针对text参数——–
-findAll(text="test")区配文本内容为test的标签,返回该内容的列表
这里写图片描述
——-针对keyword参数——–
+findAll(id="link1")寻找属性id=”link1”的标签
+findAll(class_="sister")寻找属性class=”sister”的标签,由于class是python的关键字,所以为了避免冲突,需要加”_”符号
但可以用前面方法替代:soup.findAll("", {"class":"sister"})
—–针对参数recursive——
-默认True,当等于False的时候,只查询文档的一级标签
—–针对参数limit——
+find()就是findAll()的limit参数等于1的时候


get_text(),清除标签,即获取标签里的文本信息
这里写图片描述

综合使用

上述三类方法是可以综合使用的,比如如果我想在爱丽丝文档中寻找id=”link1”的标签可以这样写:soup.findAll("p",{"class":"title"})[0].next_sibling.next_sibling.findAll(id="link1")
这里写图片描述

支持正则

由于正则可以讲的地方太多,有空再特别写一篇关于正则的总结吧


CSS选择器

同样基于爱丽丝文档
select("title")选择title标签,返回列表
这里写图片描述
select(".sister")选择class=”sister”的标签,返回列表
这里写图片描述
select("#link1")选择id=”link1”的标签,返回列表
这里写图片描述
select("head > title")选择head标签下的title标签,符号”>”左右两边一定要有空格
这里写图片描述
select("p #link2")选择p标签下符合id=link2的标签
这里写图片描述
soup.select('a[id="link3"]')选择a标签中id=link3的标签
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_41359051/article/details/80686226
今日推荐