这个库用来对网页进行解析功能,十分强大,有了它我们可以减少对正则的使用,也能顺利的从网页源码中拿到我们要的值。他是一个灵活,方便的网页解析库,处理高效,支持多种解析器。
这个库把HTML源码解析成对象与对象的关系,这样就不需要操作字符串这样简单的繁琐的操作了。
BeautifulSoup是将HTML转化为一个复杂的树形结构,每个节点都是python对象,有前端基础的同学会知道,类似DOM对象。BeautifulSoup中的对象大致有四种,Tag、NavigableString、BeautifulSoup、Comment。
bs4初相见
BeautifulSoup解析一个HTML源码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出。在实际操作中,我们会将所需要的标签通过选择器查找出来,然后通过操作Tag对象来获取所需信息。
from bs4 import BeautifulSoup html = '''
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><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>
'''
soup = BeautifulSoup(html,'html.parser')
print(soup.prettify())
##############################
输出的结果:
'''
<html>
<head>
<title>
The Dormouse's story
</title>
</head>
<body>
<p class="title">
<b>
The Dormouse's story
</b>
</p>
<p class="story">
Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1">
Elsie
</a>
,
<a class="sister" href="http://example.com/lacie" id="link2">
Lacie
</a>
and
<a class="sister" href="http://example.com/tillie" id="link3">
Tillie
</a>
;
and they lived at the bottom of a well.
</p>
<p class="story">
...
</p>
</body>
</html>
'''
BeautifulSoup解析格式化输出
这样我们就可以轻松的找到复杂的网页结构中我们需要的信息了。
print(soup.find_all('a'))#包含所有a标签的列表[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,...]
for link in soup.find_all('a'):
print(link.get('href'))#取出所有链接
print(soup.get_text())#取出标签里的文本信息
找到所有a标签下的链接
可以看出bs4的功能是十分的强大,用起来也非常的简单,较之正则表达式操作起来也是非常的简单。
解析器
Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,推荐我们安装lxml解析器,这个解析器更加强大,速度更快。
几种常见的解析器:
基本操作
标签选择器:通过这种soup.标签名 我们就可以获得这个标签的内容。通过这种方式获取标签,如果文档中有多个这样的标签,返回的结果是第一个标签的内容,如上面我们通过soup.p获取p标签,而文档中有多个p标签,但是只返回了第一个p标签内容。
print(soup.title)#<title>The Dormouse's story</title>
print(type(soup.title))#<class 'bs4.element.Tag'>是一个bs4的对象
print(soup.p)#取到的第一个标签<p class="title"><b>The Dormouse's story</b></p>
print(soup.a)#<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
获取名称:当我们通过soup.title.name的时候就可以获得该title标签的名称,即title。
print(soup.title.name)#title
print(type(soup.title.name))#<class 'str'>
print(soup.title.parent.name)#head(取到了父标签名字)
获取属性:
print(soup.p.attrs['name'])
print(soup.p['name'])
print(soup.p["class"])#['title']把所有的class名存放到一个列表中返回,也有可能属性不是class是其他
print(soup.p.attrs["class"])#['title']
获取内容:
print(soup.标签.string)
结果就可以获取第一个标签的内容。
print(soup.title.string)#The Dormouse's story
print(soup.p.string)#The Dormouse's story
嵌套选择:
print(soup.head.title.string)#The Dormouse's story
子节点和子孙节点:
print(soup.p.contents)#结果是将一个p标签下的所有子标签存入到了一个列表中
for link in soup.find_all('p'):#soup.p与link都是bs4的p标签的对象
print(link.contents)
#[<b>The Dormouse's story</b>]
#['Once upon a time there were three little sisters; and their names were\n', <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, ',\n', <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, ' and\n', <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>, ';\nand they lived at the bottom of a well.']
#['...']
children获取p标签下的所有子节点内容和通过contents获取的结果是一样的,但是不同的地方是soup.p.children是一个迭代对象,而不是列表,只能通过循环的方式获取素有的信息。
for link in soup.find_all('p'):
print(link.children.__next__())#说明它是一个可迭代对象
通过contents以及children都是获取子节点,如果想要获取子孙节点可以通过soup.descendants,这种获取的结果也是一个迭代器。
父节点和祖先节点:
通过soup.a.parent就可以获取父节点的信息;
通过list(enumerate(soup.a.parents))可以获取祖先节点,这个方法返回的结果是一个列表,会分别将a标签的父节点的信息存放到列表中,以及父节点的父节点也放到列表中,并且最后还会讲整个文档放到列表中,所有列表的最后一个元素以及倒数第二个元素都是存的整个文档的信息。
兄弟节点:
soup.a.next_siblings 获取后面的兄弟节点
soup.a.previous_siblings 获取前面的兄弟节点
soup.a.next_sibling 获取下一个兄弟标签
souo.a.previous_sinbling 获取上一个兄弟标签
find_all用法
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
假设现在爬取了这样的网页
find_all(name,attrs,recursive,text,**kwargs)可以根据标签名,属性,内容查找文档。
参数详解:
name参数:
取出标签为name的所有标签,存放到列表中,索引取出来都是bs4对象。
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all('ul'))#取出所有ul放入一个列表中,每一个ul单独取都是一个bs4对象
'''
[<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>, <ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>]
'''
print(type(soup.find_all('ul')[0]))#<class 'bs4.element.Tag'>
要获得里面的li标签则需要对每个bs4对象再次使用find_all()方法。
for ul in soup.find_all('ul'):
print(ul.find_all('li'))
'''
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]
'''
name除了可以传字符串以外还可以传正则表达式或者列表。
#name传这三种方式都可以
print(soup.find_all('p'))
print(soup.find_all(re.compile('^b')))
print(soup.find_all(['p','title']))
attr参数:
print(soup.find_all(attrs={'id': 'list-1'}))
print(soup.find_all('',{"class":"element"}))#class需要使用这种方式取
attrs可以传入字典的方式来查找标签,但是这里有个特殊的就是class,因为class在python中是特殊的字段,所以如果想要查找class相关的可以更改为soup.find_all('',{"class":"element})或者soup.findAll(class_='class')
。
text参数:
print(soup.find_all(text='Foo'))#['Foo', 'Foo']
print(soup.find_all(text='Fo'))#[]
结果返回的是查到的所有的text='Foo'的文本,必须精确匹配。
recursive参数:
recursive的默认参数为True,BeautifulSoup会查找所有后代节点,而只想搜索子节点时,可设置参数为False。
find的用法:
find(name,attrs,recursive,text,**kwargs),与find_all()的区别就是find返回的匹配结果的第一个元素。
find_parents()返回所有祖先节点,find_parent()返回直接父节点。
find_next_siblings()返回后面所有兄弟节点,find_next_sibling()返回后面第一个兄弟节点。
find_previous_siblings()返回前面所有兄弟节点,find_previous_sibling()返回前面第一个兄弟节点。
find_all_next()返回节点后所有符合条件的节点, find_next()返回第一个符合条件的节点
find_all_previous()返回节点后所有符合条件的节点, find_previous()返回第一个符合条件的节点
find的用法
css选择器
bs4提供select()直接传入CSS选择器就可以完成选择,与前端匹配css的方式基本一致。
print(soup.select('.panel .panel-heading'))#[<div class="panel-heading"><h4>Hello</h4></div>]
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))#[<li class="element">Foo</li>, <li class="element">Bar</li>]
print(type(soup.select('ul')[0]))#<class 'bs4.element.Tag'>
get_text()获取内容:
for li in soup.select('li'):
print(li.get_text())
通过[属性名]或者attrs[属性名]获得属性:
for ul in soup.select('ul'):
print(ul['id'])#两种方法的效果一致
print(ul.attrs['id'])
可以说这个库是非常的实用的,这里只是一部分常用的操作,还有更多的操作,在使用bs4的时候可以进一步查找官方文档:Beautiful Soup 4.4.0 文档。
beautifulSoup模块的更多相关文章
-
【爬虫入门手记03】爬虫解析利器beautifulSoup模块的基本应用
[爬虫入门手记03]爬虫解析利器beautifulSoup模块的基本应用 1.引言 网络爬虫最终的目的就是过滤选取网络信息,因此最重要的就是解析器了,其性能的优劣直接决定这网络爬虫的速度和效率.Bea ...
-
【网络爬虫入门03】爬虫解析利器beautifulSoup模块的基本应用
[网络爬虫入门03]爬虫解析利器beautifulSoup模块的基本应用 1.引言 网络爬虫最终的目的就是过滤选取网络信息,因此最重要的就是解析器了,其性能的优劣直接决定这网络爬虫的速度和效率.B ...
-
Python 爬虫三 beautifulsoup模块
beautifulsoup模块 BeautifulSoup模块 BeautifulSoup是一个模块,该模块用于接收一个HTML或XML字符串,然后将其进行格式化,之后遍可以使用他提供的方法进行快速查 ...
-
requsets模块和beautifulsoup模块
2.requests模块方法 requests是基于Python开发的HTTP库,使用Requests可以轻而易举的完成浏览器可有的任何操作. request.get() request.post() ...
-
BeautifulSoup 模块详解
BeautifulSoup 模块详解 BeautifulSoup是一个模块,该模块用于接收一个HTML或XML字符串,然后将其进行格式化,之后遍可以使用他提供的方法进行快速查找指定元素,从而使得在HT ...
-
03 解析库之Beautifulsoup模块
Beautifulsoup模块 一 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式 ...
-
python中BeautifulSoup模块
BeautifulSoup模块是干嘛的? 答:通过html标签去快速匹配标签中的内容.效率相对比正则会好的多.效率跟xpath模块应该差不多. 一:解析器: BeautifulSoup(html,&q ...
-
孤荷凌寒自学python第六十八天学习并实践beautifulsoup模块1
孤荷凌寒自学python第六十八天学习并实践beautifulsoup模块1 (完整学习过程屏幕记录视频地址在文末) 感觉用requests获取到网页的html源代码后,更重要的工作其实是分析得到的内 ...
-
bs4——BeautifulSoup模块:解析网页
解析由requests模块请求到的网页 import requests from bs4 import BeautifulSoup headers = {'User-Agent': 'Mozilla/ ...
-
Beautifulsoup模块基础详解
Beautifulsoup模块 官方中文文档 Beautifulsoup官方中文文档 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的 ...
随机推荐
-
rem ,em ,px的区别
参考网址:http://www.cnblogs.com/leejersey/p/3662612.html
-
PHP 导出Excel 文档
下面是总结的几个使用方法 include 'PHPExcel.php'; include 'PHPExcel/Writer/Excel2007.php'; //或者include 'PHPExcel/ ...
-
【openGL】画直线
#include "stdafx.h" #include <GL/glut.h> #include <stdlib.h> #include <math ...
-
关于Mvvm的一些深入理解
在CodePlex上找到MvvmToolkit,觉得文档写得非常好,具体,全面和深入,配合源代码来看,会对Mvvm有一个深入的理解,原文链接如下 http://www.galasoft.ch/mvvm ...
-
FWFT FIFO读操作注意
FWFT:First Word Fall Through的缩写,好像是Xilinx的说法,Altera对应的概念是Show-ahead synchronous(SASO).即数据在rdreq有效之前就 ...
-
visual studio 2010 C语言声明异常
如下这段程序,是C_Primer_plus_第五版内的一个复习题答案(感觉声明i的值有问题),在GCC上面可以运行,但是移植到VS2010就一堆错误, #include<stdio.h> ...
-
C# 数组、ArrayList、List、Dictionary的用法与区别
前言 在工作中经常遇到C#数组.ArrayList.List.Dictionary存取数据,但是该选择哪种类型进行存储数据,对于初学者的我一直不知道该怎么取舍.于是抽空好好看了下他们的用法和比较,在这 ...
-
linux下mysql重置密码
如果忘记mysql的root密码可以采取下面的步骤重新设置 1.kill掉所有mysql的进程 2.使用--skip-grant-tables的参数启动mysql shell> mysqld_s ...
-
基于vfs实现自己的文件系统
1.Linux 文件系统组成结构 linux文件系统有两个重要的特点:一个是文件系统抽象出了一个通用文件表示层--虚拟文件系统或称做VFS.另外一个重要特点就是它的文件系统支持动态安装(或说挂载等), ...
-
MySQL中 in和exists的区别
A表: 100条数据 , B: 10条数据 select * from A where id in ( select aid from B ) 先执行括号里面的查询,然后执行外面,总共需要查询的次数的 ...