上篇博客说了正则表达式,但是正则学起来比较费劲,写的时候也不好写,这次说下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使用的更多相关文章

  1. 吴裕雄--天生自然python学习笔记:Beautiful Soup 4.2.0模块

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...

  2. Python学习笔记之Beautiful Soup

    如何在Python3.x中使用Beautiful Soup 1.BeautifulSoup中文文档:http://www.crummy.com/software/BeautifulSoup/bs3/d ...

  3. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  4. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  5. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  6. python网络爬虫学习笔记

    python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  8. scrapy爬虫学习系列五:图片的抓取和下载

    系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备:      http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...

  9. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  10. Python爬虫利器二之Beautiful Soup的用法

    上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Be ...

随机推荐

  1. [Poj1273]Drainage Ditches(网络流)

    Description 给图,求最大流 最大流模板题,这里用dinic Code #include <cstdio> #include <cstring> #include & ...

  2. 51nod_1255字典序最小的子序列

    作为贪心算法的某道例题,赶脚药丸啊..这么简单的代码重构第三遍才过... 首先是贪心算法思想, 1,证明贪心算法有效性:贪心策略,使用栈结构实现,遍历输入串中所有元素,对于某个元素有如下两种情况: 情 ...

  3. 如何使用DroidPlugin——DroidPlugin初体验

    最近研究了下360的黑科技--DroidPlugin 刚开始不知道怎么用,于是看了这篇博客:http://www.jianshu.com/p/f1217cce93ef  算是引导了我,于是开始自己写写 ...

  4. getsupportfragmentmanager 没有这个方法

    让activity继承自fragmentactivity就行了.

  5. Day24&25&26&27:HTML+CSS

    1.网页得三大组成:HTML(标签.皮影的小人) \CSS(布局,皮影的装束) \JS(动作,皮影的操纵者) 2.HTML目录树 3.HTML-标签 成对<>组成,不区分大小写,自闭合标签 ...

  6. MongoDB快速入门学习笔记5 MongoDB的文档修改操作

    db.集合名称.update({query},{update},upsert, multi})query:过滤条件update:修改内容upsert:如果不存在查询条件查出的记录,是否插入一条数据,默 ...

  7. Robotium接入到Jenkins持续集成自动化测试

    6.3 将测试用例接入到Jenkins 由于我是自己学习的手机自动化测试,没有实际投入到工作中使用,jenkins的接入也没有具体操作,现摘抄一下网页:http://www.tuicool.com/a ...

  8. Leetcode 553.最优除法

    最优除法 给定一组正整数,相邻的整数之间将会进行浮点除法操作.例如, [2,3,4] -> 2 / 3 / 4 . 但是,你可以在任意位置添加任意数目的括号,来改变算数的优先级.你需要找出怎么添 ...

  9. C# 反射修改私有静态成员变量

    //动态链接库中PvsApiIfCtrl.Cls.Cls_Public类有一变量 private static string key="abcd";//下面通过反射的技术修改和获取 ...

  10. [python][django 1.10中文文档]

    https://docs.djangoproject.com/en/1.10/  官方文档,点我下载 推荐一个翻译django 1.8.2的网址: 推荐一个翻译django 1.10的博客:(着重推荐 ...