(17)python Beautiful Soup 4.6
一、安装
1.登陆官网:https://www.crummy.com/software/BeautifulSoup/
2.下载
3.解压
4.安装
cmd找到文件路径,运行
setup.py build
然后输入
python setup.py install
5.测试
打开python 导入bs4 模块看看是否报错
import bs4
没报错就看安装成功了
二、安装解析器
soup=BeautifulSoup(html文档字符串,html解析器,html文档编码)
例如:
soup=BeautifulSoup(str,"lxml",from_encoding='utf8')
安装lxml和html5lib
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, “html.parser”) |
|
|
lxml HTML 解析器 | BeautifulSoup(markup, “lxml”) |
|
|
lxml XML 解析器 | BeautifulSoup(markup, [“lxml”, “xml”])BeautifulSoup(markup, “xml”) |
|
|
html5lib | BeautifulSoup(markup, “html5lib”) |
|
|
推荐使用lxml作为解析器,因为效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定
三、 查找文档树
标签:例如<body>,<head>,<title>,<a>,<p>,<b>
获得第一个 title 标签
print soup.title
结果:<title>百度一下,你就知道</title>
获得第一个p标签(可以多个点,但下面这个例子实际body没什么意义)
print soup.body.p
结果:<p><b>手机百度</b></p>
标签的两个属性
name
得到标签本身的名称
print soup.title.name
结果:title
Attributes
通过属性,返回一个字典
print soup.a.attrs
源代码
<a href="/" id="result_logo" onmousedown="return c({'fm':'tab','tab':'logo'})"><img src="//www.baidu.com/img/baidu_jgylogo3.gif" alt="到百度首页" title="到百度首页"></a>
取值后
{'href': '/', 'id': 'result_logo', 'onmousedown': "return c({'fm':'tab','tab':'logo'})"}
获得attrs属性的值
print soup.a['id']
结果:result_logo
还可以这样,利用get方法,传入属性的名称,二者是等价的
print soup.a.get('id')
一个属性有多个值时,lxml做解析器时,会返回list
css_soup = BeautifulSoup('<p class="body strikeout"></p>','lxml')
print css_soup.p['class']
结果:['body', 'strikeout']
如果没有定义多值属性会返回一个字符串
import urllib2
from bs4 import BeautifulSoup #response =urllib2.urlopen("http://www.baidu.com")
request = urllib2.Request("http://www.baidu.com")
response = urllib2.urlopen(request)
str=response.read()
soup=BeautifulSoup(str,"lxml")
优化格式
print soup.prettify()
获得标签内容
print soup.title.string
结果:
百度一下,你就知道
第一个 p 标签的 class 属性内容
print soup.p['class']
输出第一个 a 标签的 href 属性内容
print soup.a['href']
循环a标签
for url in soup.find_all('a'):
print url.get('href')
重点介绍下find_all()方法
find_all( name , attrs , recursive , string , **kwargs )
可以只写一个name参数
find_all()的第一个参数可以是标签、正则表达式、列表、Ture、方法
返回 <class 'bs4.element.ResultSet'> 类型
标签
用于查找所有完全匹配的标签
soup.find_all('b')
会找出所有<b>的标签
正则表达式
import re
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
会找出所有b开头的标签
列表
如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回
soup.find_all(["a", "b"])
找出所有的a标签和b标签
Ture
Ture找出所有标签,配合name属性和循环,列出所有的标签名
for tag in soup.find_all(True):
print(tag.name)
方法
如果找不到合适的过滤器,自定义
待写
关键字参数
soup.find_all(id='link2')
soup.find_all(href=re.compile("elsie"))
soup.find_all(id=True)
同时过滤多属性
soup.find_all(href=re.compile("elsie"), id='link1')
按class搜索
参数不能用class,这是python的关键字,要用class_参数用法一样
soup.find_all("a", class_="sister")
通过内容查找
string参数
soup.find_all("a", string="Elsie")
限制返回结果的数量
limit参数
soup.find_all("a", limit=2)
recursive
参数
参数 recursive=False 表示只能查他的下一层节点,没有的话返回[]
<html>
<head>
<title>
The Dormouse's story
</title>
</head>
soup.html.find_all("title")
# [<title>The Dormouse's story</title>] soup.html.find_all("title", recursive=False)
# []
find_all()方法简写
因为find_all()是最常用的方法,所以程序上可以把他省略
soup.find_all("a")相当于soup("a")
find()方法
soup.find_all('title', limit=1)相当于soup.find('title')
区别是find_all返回值是一个元素列表, find直接返回结果
find_all找不到目标时返回空列表,find返回None
soup.head.title的原理就是soup.find("head").find("title")
find_parents() 和 find_parent()
用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容. 我们从一个文档中的一个叶子节点开始
find_next_siblings()和find_next_sibling()
属性对当前tag的后面解析
find_next_siblings():方法返回所有符合条件的后面的兄弟节点
find_next_sibling():只返回符合条件的后面的第一个tag节点
find_previous_siblings和 find_previous_sibling()
属性对当前tag的前面解析
find_previous_siblings:方法返回所有符合条件的前面的兄弟节点
find_previous_sibling():方法返回第一个符合条件的前面的兄弟节点
find_all_next() 和 find_next()
对当前tag的之后的 tag和字符串进行迭代
find_all_next()
方法返回所有符合条件的节点, find_next()
方法返回第一个符合条件的节点
find_all_previous() 和 find_previous()
对当前节点前面的tag和字符串进行迭代
find_all_previous()
方法返回所有符合条件的节点, find_previous()
方法返回第一个符合条件的节点
三、CSS选择器
BeautifulSoup
对象的 .select()
方法中传入字符串参数, 即可使用CSS选择器的语法找到tag
代写
四、修改文档树
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b tag.name = "blockquote"
tag['class'] = 'verybold'
tag['id'] = 1
tag
# <blockquote class="verybold" id="1">Extremely bold</blockquote> del tag['class']
del tag['id']
tag
# <blockquote>Extremely bold</blockquote>
修改 .string
给tag的 .string
属性赋值,就相当于用当前的内容替代了原来的内容:
markup = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(markup) tag = soup.a
tag.string = "New link text."
tag
# <a href="http://example.com/">New link text.</a>
注意: 如果当前的tag包含了其它tag,那么给它的 .string
属性赋值会覆盖掉原有的所有内容包括子tag
append()
Tag.append()
方法想tag中添加内容,就好像Python的列表的 .append()
方法:
soup = BeautifulSoup("<a>Foo</a>")
soup.a.append("Bar") soup
# <html><head></head><body><a>FooBar</a></body></html>
soup.a.contents
# [u'Foo', u'Bar']
clear()
Tag.clear()
方法移除当前tag的内容:
markup = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(markup)
tag = soup.a tag.clear()
tag
# <a href="http://example.com/"></a>
五、输出
格式化输出
markup = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(markup)
soup.prettify()
# '<html>\n <head>\n </head>\n <body>\n <a href="http://example.com/">\n...' print(soup.prettify())
# <html>
# <head>
# </head>
# <body>
# <a href="http://example.com/">
# I linked to
# <i>
# example.com
# </i>
# </a>
# </body>
# </html>
BeautifulSoup
对象和它的tag节点都可以调用 prettify()
方法:
print(soup.a.prettify())
# <a href="http://example.com/">
# I linked to
# <i>
# example.com
# </i>
# </a>
压缩输出
如果只想得到结果字符串,不重视格式,那么可以对一个 BeautifulSoup
对象或 Tag
对象使用Python的 unicode()
或 str()
方法:
str(soup)
# '<html><head></head><body><a href="http://example.com/">I linked to <i>example.com</i></a></body></html>' unicode(soup.a)
# u'<a href="http://example.com/">I linked to <i>example.com</i></a>'
str()
方法返回UTF-8编码的字符串,可以指定 编码 的设置.
还可以调用 encode()
方法获得字节码或调用 decode()
方法获得Unicode.
输出格式
Beautiful Soup输出是会将HTML中的特殊字符转换成Unicode,比如“&lquot;”:
soup = BeautifulSoup("“Dammit!” he said.")
unicode(soup)
# u'<html><head></head><body>\u201cDammit!\u201d he said.</body></html>'
如果将文档转换成字符串,Unicode编码会被编码成UTF-8.这样就无法正确显示HTML特殊字符了:
str(soup)
# '<html><head></head><body>\xe2\x80\x9cDammit!\xe2\x80\x9d he said.</body></html>'
get_text()
如果只想得到tag中包含的文本内容,那么可以用 get_text()
方法,这个方法获取到tag中包含的所有文版内容包括子孙tag中的内容,并将结果作为Unicode字符串返回:
markup = '<a href="http://example.com/">\nI linked to <i>example.com</i>\n</a>'
soup = BeautifulSoup(markup) soup.get_text()
u'\nI linked to example.com\n'
soup.i.get_text()
u'example.com'
可以通过参数指定tag的文本内容的分隔符:
# soup.get_text("|")
u'\nI linked to |example.com|\n'
还可以去除获得文本内容的前后空白:
# soup.get_text("|", strip=True)
u'I linked to|example.com'
或者使用 .stripped_strings 生成器,获得文本列表后手动处理列表:
[text for text in soup.stripped_strings]
# [u'I linked to', u'example.com']
六、指定文档解析器
解析器之间的区别
Beautiful Soup为不同的解析器提供了相同的接口,但解析器本身时有区别的.同一篇文档被不同的解析器解析后可能会生成不同结构的树型文档.区别最大的是HTML解析器和XML解析器,看下面片段被解析成HTML结构:
BeautifulSoup("<a><b /></a>")
# <html><head></head><body><a><b></b></a></body></html>
因为空标签<b />不符合HTML标准,所以解析器把它解析成<b></b>
同样的文档使用XML解析如下(解析XML需要安装lxml库).注意,空标签<b />依然被保留,并且文档前添加了XML头,而不是被包含在<html>标签内:
BeautifulSoup("<a><b /></a>", "xml")
# <?xml version="1.0" encoding="utf-8"?>
# <a><b/></a>
HTML解析器之间也有区别,如果被解析的HTML文档是标准格式,那么解析器之间没有任何差别,只是解析速度不同,结果都会返回正确的文档树.
但是如果被解析文档不是标准格式,那么不同的解析器返回结果可能不同.下面例子中,使用lxml解析错误格式的文档,结果</p>标签被直接忽略掉了:
BeautifulSoup("<a></p>", "lxml")
# <html><body><a></a></body></html>
使用html5lib库解析相同文档会得到不同的结果:
BeautifulSoup("<a></p>", "html5lib")
# <html><head></head><body><a><p></p></a></body></html>
html5lib库没有忽略掉</p>标签,而是自动补全了标签,还给文档树添加了<head>标签.
使用pyhton内置库解析结果如下:
BeautifulSoup("<a></p>", "html.parser")
# <a></a>
与lxml库类似的,Python内置库忽略掉了</p>标签,与html5lib库不同的是标准库没有尝试创建符合标准的文档格式或将文档片段包含在<body>标签内,与lxml不同的是标准库甚至连<html>标签都没有尝试去添加.
因为文档片段“<a></p>”是错误格式,所以以上解析方式都能算作”正确”,html5lib库使用的是HTML5的部分标准,所以最接近”正确”.不过所有解析器的结构都能够被认为是”正常”的.
不同的解析器可能影响代码执行结果,如果在分发给别人的代码中使用了 BeautifulSoup
,那么最好注明使用了哪种解析器,以减少不必要的麻烦.
七、编码
任何HTML或XML文档都有自己的编码方式,比如ASCII 或 UTF-8,但是使用Beautiful Soup解析后,文档都被转换成了Unicode:
markup = "<h1>Sacr\xc3\xa9 bleu!</h1>"
soup = BeautifulSoup(markup)
soup.h1
# <h1>Sacré bleu!</h1>
soup.h1.string
# u'Sacr\xe9 bleu!'
这不是魔术(但很神奇),Beautiful Soup用了 `编码自动检测`_ 子库来识别当前文档编码并转换成Unicode编码. BeautifulSoup
对象的 .original_encoding
属性记录了自动识别编码的结果:
soup.original_encoding
'utf-8'
`编码自动检测`_ 功能大部分时候都能猜对编码格式,但有时候也会出错.有时候即使猜测正确,也是在逐个字节的遍历整个文档后才猜对的,这样很慢.如果预先知道文档编码,可以设置编码参数来减少自动检查编码出错的概率并且提高文档解析速度.在创建 BeautifulSoup
对象的时候设置 from_encoding
参数.
下面一段文档用了ISO-8859-8编码方式,这段文档太短,结果Beautiful Soup以为文档是用ISO-8859-7编码:
markup = b"<h1>\xed\xe5\xec\xf9</h1>"
soup = BeautifulSoup(markup)
soup.h1
<h1>νεμω</h1>
soup.original_encoding
'ISO-8859-7'
通过传入 from_encoding
参数来指定编码方式:
soup = BeautifulSoup(markup, from_encoding="iso-8859-8")
soup.h1
<h1>םולש</h1>
soup.original_encoding
'iso8859-8'
如果仅知道文档采用了Unicode编码, 但不知道具体编码. 可以先自己猜测, 猜测错误(依旧是乱码)时, 可以把错误编码作为 exclude_encodings
参数, 这样文档就不会尝试使用这种编码了解码了. 译者备注: 在没有指定编码的情况下, BS会自己猜测编码, 把不正确的编码排除掉, BS就更容易猜到正确编码.
soup = BeautifulSoup(markup, exclude_encodings=["ISO-8859-7"])
soup.h1
<h1>םולש</h1>
soup.original_encoding
'WINDOWS-1255'
少数情况下(通常是UTF-8编码的文档中包含了其它编码格式的文件),想获得正确的Unicode编码就不得不将文档中少数特殊编码字符替换成特殊Unicode编码,“REPLACEMENT CHARACTER” (U+FFFD, �) .如果Beautifu Soup猜测文档编码时作了特殊字符的替换,那么Beautiful Soup会把UnicodeDammit
或 BeautifulSoup
对象的 .contains_replacement_characters
属性标记为 True
.这样就可以知道当前文档进行Unicode编码后丢失了一部分特殊内容字符.如果文档中包含�而.contains_replacement_characters
属性是 False
,则表示�就是文档中原来的字符,不是转码失败.
(17)python Beautiful Soup 4.6的更多相关文章
- python Beautiful Soup的使用
上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表 达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫B ...
- 推荐一些python Beautiful Soup学习网址
前言:这几天忙着写分析报告,实在没精力去研究django,虽然抽时间去看了几遍中文文档,还是等实际实践后写几篇操作文章吧! 正文:以下是本人前段时间学习bs4库找的一些网址,在学习的可以参考下,有点多 ...
- Python Beautiful Soup学习之HTML标签补全功能
Beautiful Soup是一个非常流行的Python模块.该模块可以解析网页,并提供定位内容的便捷接口. 使用下面两个命令安装: pip install beautifulsoup4 或者 sud ...
- python beautiful soup库的超详细用法
原文地址https://blog.csdn.net/love666666shen/article/details/77512353 参考文章https://cuiqingcai.com/1319.ht ...
- Python Beautiful Soup 解析库的使用
Beautiful Soup 借助网页的结构和属性等特性来解析网页,这样就可以省去复杂的正则表达式的编写. Beautiful Soup是Python的一个HTML或XML的解析库. 1.解析器 解析 ...
- python beautiful soup
官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/ 使用前需要先安装模块,并安装解析器 pip install beautif ...
- Python Beautiful Soup 4
Beautiful Soup 是一个灵活方便的网页解析库,利用它不用编写正则表达式即可方便地提取的网页信息 官方文档:https://www.crummy.com/software/Beautiful ...
- python Beautiful Soup 采集it books pdf,免费下载
http://www.allitebooks.org/ 是我见过最良心的网站,所有书籍免费下载 周末无聊,尝试采集此站所有Pdf书籍. 采用技术 python3.5 Beautiful soup 分享 ...
- Python Beautiful Soup库
Beautiful Soup库 Beautiful Soup库:https://www.crummy.com/software/BeautifulSoup/ 安装Beautiful Soup: 使用B ...
随机推荐
- unity安装记录
官网直接下载(http://unity3d.com/cn/) 下载完后,会要求输入账号密码.我是先在官网进行一个账号注册,然后登陆即可. 首先会要你输入一个已有的邮箱,进行认证.进入自己邮箱,点击链接 ...
- 搭建Data Mining环境(Spark版本)
前言:工欲善其事,必先利其器.倘若不懂得构建一套大数据挖掘环境,何来谈Data Mining!何来领悟“Data Mining Engineer”中的工程二字!也仅仅是在做数据分析相关的事罢了!此文来 ...
- 第三模块 面向对象& 网络编程基础 实战考核
1.简述构造方法和析构方法. 构造方法(__init__):主要作用是实例化时给实例一些初始化参数,或执行一些其它的初始化工作,总之因为这个__init__只要一实例化, 就会自动执行,不管你在这个方 ...
- P1616 疯狂的采药
P1616 疯狂的采药 题目背景 此题为NOIP2005普及组第三题的疯狂版. 此题为纪念LiYuxiang而生. 题目描述 LiYuxiang是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为 ...
- Unable to execute dex: Multiple dex files define Lcom/myapp/R$array;
Unable to execute dex: Multiple dex files define Lcom/myapp/R$array; 我这个问题最后解决方式是,吧工程里面用同一个v4包. 很明显, ...
- SpringMvc路径参数和url的两种实现方式
我们经常采用的SpringMvc路径参数经常的操作是在url后面采用?参数名=值1&参数名2=值2这种方式实现 RequestMapping的作用: 1)当作用在controller时,我们通 ...
- leetcode 【 Best Time to Buy and Sell Stock 】python 实现
思路: Say you have an array for which the ith element is the price of a given stock on day i. If you w ...
- leetcode 【 Remove Duplicates from Sorted Array II 】python 实现
题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...
- Http请求连接池-HttpClient的AbstractConnPool源码分析
在做服务化拆分的时候,若不是性能要求特别高的场景,我们一般对外暴露Http服务.Spring里提供了一个模板类RestTemplate,通过配置RestTemplate,我们可以快速地访问外部的Htt ...
- sqlserver 表值函数
一.单语句表值函数 ALTER function [dbo].[uf_get_jxc_da_sum](@dt char(8),@dt2 char(8)) RETURNS table as return ...