我们先前进行网站页面内容解析的过程中,通常选择运用正则表达式来完成此任务。然而,正如前面几篇文章所阐述和分析的那样,无论是正则表达式还是XPath,它们虽各自具备适应不同应用场景的优势,却也都存在着各自难以避免的缺陷。例如,正则表达式具有相对复杂的语法结构并且需要大量的编程知识才能熟练掌握;而XPath虽然使得实现路径查找更为简洁易懂,但却需要编写复杂的节点路径编码。因此,为了充分利用HTML读取技术的强大功能,同时追求更加简明直观的操作体验,本文将向您推荐Beautiful Soup这款强大的三方工具。那么,它是否能够如其名字那般“美丽”呢?接下来,让我们共同揭开这个谜团!
Beautiful Soup 也是一个 Python 的 XML 和 HTML 的解析库,其提供了简单的,Python 式的函数来处理导航,搜索,修改分析树等功能(来自官方介绍)。
Beautiful Soup来源于爱丽丝梦游仙境
在使用 Beautiful Soup 之前,需要安装好 lxml(推荐 lxml 解析器) 和其自身的库。
pip install beautifulsoup4
pip install lxml
beautiful Soup 在解析过程中依赖各种解析器,除了支持 Python 标准的解析器外,还支持其他的三方解析器(如: lxml)。
各种解析器优缺点
一般在使用的过程中,推荐使用 lxml,因为 lxml 本身也是一个非常优秀的解析库,也支持 XML 的解析。
假设有以下内容的 html 文档。
<!DOCTYPE html>
<html lang="en">
<body>
<div>
<ul>
<li class="class-0">
<a href="a.html">
<span>第一个标签</span>
</a>
</li>
</ul>
</div>
</body>
</html>
from bs4 import BeautifulSoup
# 初始化BeautifulSoup,并指定lxml为解析器
soup = BeautifulSoup(open("index.html"),
"lxml")
# 获取span标签
print(soup.span)
print(soup.span.string)
# <span>第一个标签</span>
# 第一个标签
如上代码,BeautifulSoup 方法有有两个参数, 第一个参数接受一个 html 文档,第二个参数指定解释器类型,这样就初始化了一个BeautifulSoup 的对象,后续就可以使用这个对象来解析和获取 HTML 中的数据,如上方获取 span, 并获取 span 的内容。
获取 bs 对象有两种方式,一种是直接使用文本字符,另一种是读取文档:
from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html>data</html>")
通过上边的代码示例可以看到,在获取到 bs 对象后,后续直接调用节点名称就可以获取到节点对象,再调用 string 属性就可以获取到节点的文本内容,相较于使用正则表达式或者 XPath 效率是非常高的。
html_doc = """
<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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
# 获取title标签
soup.title
# <title>The Dormouse's story</title>
#获取title标签名字
soup.title.name
# u'title'
#获取title标签文本内容
soup.title.string
# u'The Dormouse's story'
#获取title父标签
soup.title.parent.name
# u'head'
#获取p标签
soup.p
# <p class="title"><b>The Dormouse's story</b></p>
#获取p标签的class属性
soup.p['class']
# u'title'
# 获取a标签
soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
# 查找所有的a标签
soup.find_all('a')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
# 查找id为link3的标签
soup.find(id="link3")
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
虽然在 Beautiful Soup 中可以将复杂的 HTML 文档转换为树形结构,但是从大体可归纳为以下 4 个对象:
Tag:Tag 对象用于表示 HTML 和 XML 文档中的 tag 标签。
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
type(tag)
# <class 'bs4.element.Tag'>
tag.name
# u'b'
tag['class']
# u'boldest'
如上任何的标签在Beautiful Soup 都表示为一个 Tag 对象,且从该对象上获取到当前标签的各种属性值。
NavigableString :表示 Tag 中被包裹的字符串
tag.string
# u'Extremely bold'
type(tag.string)
# <class 'bs4.element.NavigableString'>
BeautifulSoup :该对象表示文档整体的一个类,即初始化后获得的类,所以获取到该类,就获取到了整个文档。需要注意需要和上边 Tag 类做出区分,BeautifulSoup 类是特殊的 Tag 类。
Comment :表示文档中的注释内容,其本质也是一个特殊的NavigableString 对象,但由于其特殊性,单独做封装处理。
除了上边的属性选择器和方法选择器外,Beautiful Soup 还提供 CSS 选择器,这对于有前端样式开发经验的同学来说是非常给力的一个特性。通过 CSS 选择器也可以轻松的选定各个节点,但在使用中和上边的有所不同需要调用 .selsect() 方法, 如下方代码:
soup.select("title")
# [<title>The Dormouse's story</title>]
soup.select("p:nth-of-type(3)")
# [<p class="story">...</p>]
有不熟悉css选择器的小伙伴可以在w3c上学习,一般基础的选择器就可胜任绝大多数数据获取的任务。
天晚上竟然忙忘了,忘了给大家推文了。等到反应过来的时候,已经晚了,懒得不想写了。最近确实很忙,各种事一堆,真的是希望自己能够有个三头六臂,踩着风火轮,效率高点就好了。
今天给大家推荐一个不错的小程序富文本解析器。
我们都知道今年小程序不是一般的火,很多人都在做微信小程序,我也有一直在开发,最近正好用到了富文本解析的问题,所以,在 GitHub 上找到了一个不错的开源库。用起来,还挺顺手,挺不错的,所以非常值得推荐给大家。
这个富文本解析器不仅支持解析转换 HTML ,还支持 MarkDown 呢,它就是:wxParse - 微信小程序富文本解析组件。其作者用就是:将 Html/Markdown 转换为微信小程序的可视化方案。
特性如下:
效果图,也如下:
真的非常不错哦。使用方法很简单,在这里我就不介绍了,大家直接去看项目中的介绍吧!里面用法介绍的很清楚,详细。
开源项目地址:https://github.com/icindy/wxParse
开源项目作者:icindy
今天的推荐不知道大家喜欢吗?如果你喜欢,请在文章底部留言和点赞,以表示对我的支持,你们的留言和点赞是我持续更新的动力哦!
章鱼猫在此感谢大家的关注和支持。喜欢我,就赶紧关注我,给我点赞吧!
互联网+数据+人工智能时代,仍然有越来越多的网页数据采集需求,且案例众多,网页数据采集在企业中落地的实际应用也在不断地显著增加。实际工作中可能需要为一个旅游网站获取航班时间或Airbnb列表,或者可能需要收集数据,例如来自不同电子商务网站的价格表,以便进行价格比较。很多时候也会出于个人需要,比如为机器学习收集训练和测试数据集等。这就是web网页数据采集发挥作用的地方。
在这里,我们将探讨最好的网页数据采集工具。
https://github.com/puppeteer/puppeteer
Puppeteer是Google放出的“终极”大招,它不只是一个网页数据采集工具,实际上是一个Node库,它提供了一个高阶API,类似于Selenium Webdriver的高级别API,默认是通过DevTools协议控制无界面Chrome,还可以通过配置用于有界面Chrome。
使用Puppeteer,我们可以做以下事情:
# 用来生成网页截图或PDF文件。
# 用来创建全新的自动化测试环境。
# 用来捕捉网页的时间线轨迹以诊断性能问题。
# 抓取一个SPA(单页应用程序)并生成网页渲染之前的内容(服务器端渲染(SSR))。
API像自然语言一样简洁明了,没有callback,几行代码就能搞定我们所需的一切。
https://github.com/cheeriojs/cheerio
Cheerio是一个标记解析库,提供了对结果数据(比如服务端接口返回的数据)结构进行解析的API,Cheerio最好的一点是它不像web浏览器那样解释结果数据。然而,它既不产生视觉呈现、也不加载外部资源或请求CSS。如果实际项目中需要上面这些能力的话,就需要考虑类似PhantomJS这样的项目。
值得注意的是,用Node.js采集数据在Cheerio中要容易得多。
比如采集http://v.163.com/special/opencourse/englishs1.html:
https://github.com/request/request-promise
Request-Promise是npm库中的一个变体,它通过自动化的浏览器提供了一个更快的解决方案。当内容不是动态呈现时,可以使用此网页数据采集工具。如果要处理的网站有一个认证系统,它可以是一个更先进的解决方案。如果我们把它和Puppeteer相比,它的用法正好相反。
https://github.com/segmentio/nightmare
Nightmare是一个高级的浏览器自动化库,它以浏览器的形式运行Electron程序。Electron (https://electronjs.org/)是一个使用 JavaScript, HTML 和 CSS 等 Web 技术创建原生程序的框架,兼容Mac、Windows和Linux,可以构建出三个平台的桌面应用程序,它负责比较难搞的部分,我们只需把精力放在应用的核心上即可【Electron刚刚加入了 OpenJS 基金会】。Nightmare是一个浓缩的版本,或者我们可以说,是一个简化版的Puppeteer。它有提供更多灵活性的插件,包括对文件下载的支持。
Nightmare的目标是对外公开几个使用起来像是同步的方法调用,比如goto、type和click,而不是深度嵌套的回调。最初是为在没有api的站点之间自动化执行任务而设计的,但最常用于UI测试和数据采集。
还可以运行mocha测试。
https://www.npmjs.com/package/osmosis
Osmosis是一个HTML/XML解析器和网页数据采集工具。它是用Node.js编写的,用CSS3/xpath选择器和轻量级HTTP包装器打包。如果我们将它与Cheerio、jQuery和jsdom进行比较,则它没有显著的依赖性。
实例代码如下:
【202001】
*请认真填写需求信息,我们会在24小时内与您取得联系。