爬虫学习笔记(五) Beautiful Soup使用
上篇博客说了正则表达式,但是正则学起来比较费劲,写的时候也不好写,这次说下Beautiful Soup怎么用,这个模块是用来解析html的,它操作很简单,用起来比较方便,比正则学习起来简单多了。
这是第三方模块需要安装
1
2
3
|
pip install beautifulsoup4
pip install lxml
|
Beautiful Soup对象
Beautiful将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
Tag
标签,通过html的标签取到内容, 比如说a标签,如果有多个的话,取的是第一个。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
html = """
<html><head><title>BestTest</title></head>
<body>
<div>
<p class="content">最专业的软件测试培训
<a href="http://www.besttest.cn" class="link" id="link1"><!--首页--></a>,
<a href="http://www.besttest.cn/page/3.html" class="link" id="link2">BestTest性能测试</a> and
<a href="http://www.besttest.cn/page/47.html" class="link" id="link3">BestTest自动化测试</a>;
课程详情请点击上面的链接.</p>
<p class="content">.这是广告植入.</p>
<p class="title">BestTest is best</p>
</div>
</body>
</html>
"""
obj = BeautifulSoup(html,'lxml')#后面是指定使用lxml解析,lxml解析速度比较快,容错高。
print(obj.prettify()) #格式化输出html
print(obj.title) #取title这个标签里面的内容
print(obj.p)
#tag有两个属性,一个是name,一个是attr
# name ,name这个属性就是标签的名字,比如说a标签就是打印的name就是a
# attrs,attrs这个是这个tag的属性,比如说上面a标签的属性有 class、href、id ,他是一个字典
#既然attrs是一个字典,那就能通过key来取值
print(obj.a.name) #a标签的name,也就是a
print(obj.a.attrs) #a标签的属性,也就是class href id这些,以及对应的值是什么
print(obj.a.attrs['href']) #取到a标签的href熟悉,也就是,http://www.besttest.cn
print(obj.a.attrs.get('href')) #因为attrs是一个字典,所以也可以用.get方法取值和上面的中括号取值一样
|
NavigableString
也就是内容,获取到一个标签里面的内容,文字,比如说上面title标签里面内容获取到,也就是besttest直接用tag.string即可。
1
2
3
|
print(obj.title.string) #BestTest
print(obj.a.string) #首页
print(type(obj.title.string)) # <class 'bs4.element.NavigableString'> NavigableString的类型
|
Beautifulobj
Beautifulobj对象就是代表整个html,比如说上面的obj就是Beautifulobj对象,通过它来操作各个标签
1
|
print(type(obj)) #Beautifulobj对象
|
Comment
Comment 对象是一个特殊类型的 NavigableString对象, 其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦。例如上面的一个a标签里面,首页是被注释了的。
1
2
3
|
print(obj.a.string) #首页,不包括 <!-- -->注释的
print(type(obj.a.string)) # <class 'bs4.element.Comment'> Comment类型
#这其实是注释的内容,咱们用string取出来的时候是不带注释符号的所以这里要注意一下
|
重点操作
上面的都是通过某个标签获取到的,如果想直接获取到某些标签,获取包含某些属性的就要用其他的方法了。
搜索标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# find_all方法 find_all( name , attrs , recursive , text , **kwargs )
#find_all方法用来搜索当前所有的tag,判断是否符合过滤条件,如果符合的话,返回符合条件的列表
print(obj.find_all('p'))#找到所有p标签
print(obj.find_all(['a','p']))#找到所有a和p标签
#指定属性
print(obj.find_all(id='link1')) #找到id为link1的
print(obj.find_all(id=['link1','link2'])) #找到id为link1和link2的
#因为class在python里面是关键字,如果要找class属性的,不能直接写class,要写class_
print(obj.find_all(class_='link')) #class为link的,
print(obj.find_all(class_=['link','content']))#class为link和conent的
print(obj.find_all(attrs={'class':'link','id':'link1'})) #多个属性也可以直接写成一个字典,把属性名写成key,值写成value
print(obj.find_all('p',class_='content')) #从p标签里面找到class为conent的
print(type(obj.find(class_='link')))#find方法和findall方法的区别是,findall会返回所有的标签,放到一个list里面
#find方法返回的是一个标签,找到多个的话,取第一个。其他用法都是一样的
|
css选择器
css选择器就是通过css获取元素的方式来获取html的标签,如果对css比较熟悉的人用起来就很方便了,在css选择器中 "." 代表选择的class,"#"代表选择的id。
1
2
3
4
5
6
7
8
9
10
11
|
print('p',obj.select('p')) #通过标签选择
print(obj.select('a')) #通过标签选择
print(obj.select('.content'))#通过类名选择
print(obj.select('#link1'))#通过id选择
print(obj.select('p .link'))#组合查找,找p标签下面class为title的
print(obj.select('p #link1'))#组合查找,找p标签下面id为link1的
print(obj.select('a#link1'))#组合查找,找a标签里面id为link1的,和不加空格的区别是,在同级别找的
print(obj.select('p > a'))#标签组合查找,找到p标签下面的a标签
print(obj.select('a[class=link]'))#属性查找,找到a标签下面class为link的
print(obj.select('p a[href=http://www.besttest.cn/page/47.html]'))#组合使用,从p标签下面的a标签找到href为http://www.besttest.cn/page/47.html的
|
节点内容
节点就是怎么获取html的各个节点,比如说和div同级的其他div,div下面的子标签等等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# contents tag 的 .contents 属性可以将tag的子节点以列表的方式输出
#children children和contents一样,也是获取子节点,只不过children不是列表,而是一个生成器
print(obj.div.contents) #获取到div下面的所有tag
print(obj.div.children) #这个是一个生成器,打印出来是一个生成器对象,想获取的话,就要循环了
for chil in obj.div.children:
print(chil)
# 通过contents以及children都是获取子节点,如果想要获取子孙节点可以通过descendants
# print(obj.descendants)同时这种获取的结果也是一个迭代器
#
# 父节点和祖先节点
#
# 通过obj.a.parent就可以获取父节点的信息
#
# 通过obj.a.parents可以获取祖先节点,这个方法返回的结果是一个列表,会分别将a标签的父节点的信息存放到列表中,以及父节点的父节点也放到列表中,并且最后还会讲整个文档放到列表中,所有列表的最后一个元素以及倒数第二个元素都是存的整个文档的信息
#
# 兄弟节点
#
# obj.a.next_siblings 获取后面的兄弟节点
# obj.a.previous_siblings 获取前面的兄弟节点
# obj.a.next_sibling 获取下一个兄弟标签
# obj.a.previous_sinbling 获取上一个兄弟标签
|
总结
主要说了怎么获取到html里面的各种标签、元素,修改和删除没有写,因为爬虫一般用不到修改,获取数据就够了。find_all()和css选择器都很常用,如果对css比较熟悉的话,建议使用css选择器。标签搜索和css选择器这里非常的常用。
爬虫学习笔记(五) Beautiful Soup使用的更多相关文章
- 吴裕雄--天生自然python学习笔记:Beautiful Soup 4.2.0模块
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...
- Python学习笔记之Beautiful Soup
如何在Python3.x中使用Beautiful Soup 1.BeautifulSoup中文文档:http://www.crummy.com/software/BeautifulSoup/bs3/d ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- python网络爬虫学习笔记
python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- scrapy爬虫学习系列五:图片的抓取和下载
系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备: http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- Python爬虫利器二之Beautiful Soup的用法
上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Be ...
随机推荐
- ARM linux中断总结
Linux异常处理体系结构 Linux异常体系之vector_stub宏解析 Linux异常体系之stubs_offset Linux中断体系结构 ARM系统调用
- windows7下将Cygwin加入右键菜单,并从当前目录打开
第一步:修改windows注册表 1·开始->运行(或者win键+R),输入REGEDIT,回车,打开注册表编辑器: 2·找到HKEY_CLASSES_ROOT\Directory\Backgr ...
- 51nod_1255字典序最小的子序列
作为贪心算法的某道例题,赶脚药丸啊..这么简单的代码重构第三遍才过... 首先是贪心算法思想, 1,证明贪心算法有效性:贪心策略,使用栈结构实现,遍历输入串中所有元素,对于某个元素有如下两种情况: 情 ...
- Java文件 ---流
分类 根据数据走向,分为输入流.输出流 根据处理的数据类型,分为字节流.字符流 字节流 可以处理所有类型的数据,如MP3.图片.文字.视频等.在读取时,读到一个字节就返回一个字节. 在Java中对应的 ...
- Autofac Mvc5 Nuget
Autofac 3.5.2 Install-Package Autofac -Version 3.5.2 Autofac ASP.NET MVC 5 Integration 3.3.3 Install ...
- IOS开发学习笔记025-xib和storyboard
stotyboard : 描述软件界面,大范围,比较适合整个软件的所有界面 xib文件的使用:描述软件界面,小范围,比较适合描述小界面 在xcode新建文件窗口可以看到两个文件,storyboard和 ...
- day05_07 标志位讲解
continue: 需求:大于5才打印 for i in range(10): if i<6 : continue print(i) continue作用:结束本次循环,继续下次循环 break ...
- Leetcode 647.回文子串
回文子串 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串. 示例 1: 输入: "abc&qu ...
- 【转】Unity3D学习日记(二)使用UGUI制作虚拟摇杆控制摄像机
http://blog.csdn.net/begonia__z/article/details/51178907 前天撸了一个简单的UGUI虚拟摇杆,今天我就利用前天做的虚拟摇杆做了一个简单的摄像机控 ...
- vim 查找命令
/要查找的内容 自光标起始位置向下查找 ?要查找的内容 自光标起始位置向上查找