人生苦短, 我用 Python
前文传送门:
小白学 Python 爬虫(1): 开篇 https://www.geekdigging.com/2019/11/13/3303836941/
小白学 Python 爬虫 (2): 前置准备(一) 基本类库的安装 https://www.geekdigging.com/2019/11/20/2586166930/
小白学 Python 爬虫(3): 前置准备(二)Linux 基础入门 https://www.geekdigging.com/2019/11/21/1005563697/
小白学 Python 爬虫(4): 前置准备(三)Docker 基础入门 https://www.geekdigging.com/2019/11/22/3679472340/
小白学 Python 爬虫 (5): 前置准备(四) 数据库基础 https://www.geekdigging.com/2019/11/24/334078215/
小白学 Python 爬虫 (6): 前置准备(五) 爬虫框架的安装 https://www.geekdigging.com/2019/11/25/1881661601/
小白学 Python 爬虫(7):HTTP 基础 https://www.geekdigging.com/2019/11/26/1197821400/
小白学 Python 爬虫(8): 网页基础 https://www.geekdigging.com/2019/11/27/101847406/
小白学 Python 爬虫(9): 爬虫基础 https://www.geekdigging.com/2019/11/28/1668465912/
小白学 Python 爬虫(10):Session 和 Cookies https://www.geekdigging.com/2019/12/01/2475257648/
小白学 Python 爬虫(11):urllib 基础使用(一) https://www.geekdigging.com/2019/12/02/2333822325/
小白学 Python 爬虫(12):urllib 基础使用(二) https://www.geekdigging.com/2019/12/03/819896244/
小白学 Python 爬虫(13):urllib 基础使用(三) https://www.geekdigging.com/2019/12/04/2992515886/
小白学 Python 爬虫(14):urllib 基础使用(四) https://www.geekdigging.com/2019/12/05/104488944/
小白学 Python 爬虫(15):urllib 基础使用(五) https://www.geekdigging.com/2019/12/07/2788855167/
小白学 Python 爬虫(16):urllib 实战之爬取妹子图 https://www.geekdigging.com/2019/12/09/1691033431/
小白学 Python 爬虫(17):Requests 基础使用 https://www.geekdigging.com/2019/12/10/1910005577/
小白学 Python 爬虫(18):Requests 进阶操作 https://www.geekdigging.com/2019/12/11/1468953802/
小白学 Python 爬虫(19):Xpath 基操 https://www.geekdigging.com/2019/12/12/3568648672/
小白学 Python 爬虫(20):Xpath 进阶 https://www.geekdigging.com/2019/12/13/2569867940/
首先当然是各种资料地址敬上:
官方网站: https://www.crummy.com/software/BeautifulSoup/
官方文档:
中文文档:
先看下官方对自己的介绍:
Beautiful Soup 提供一些简单的, Python 式的函数来处理导航, 搜索, 修改分析树等功能. 它是一个工具箱, 通过解析文档为用户提供需要抓取的数据, 因为简单, 所以不需要多少代码就可以写出一个完整的应用程序.
Beautiful Soup 自动将输入文档转换为 Unicode 编码, 输出文档转换为 UTF-8 编码. 你不需要考虑编码方式, 除非文档没有指定一个编码方式, 这时你仅仅需要说明一下原始编码方式就可以了.
Beautiful Soup 已成为和 lxml , html6lib 一样出色的 Python 解释器, 为用户灵活地提供不同的解析策略或强劲的速度.
讲人话就是 Beautiful Soup 是一个非常好用, 速度又快的 HTML 或 xml 的解析库.
Beautiful Soup 在解析时实际上依赖解析器, 它除了支持 Python 标准库中的 HTML 解析器外, 还支持一些第三方解析器. 下表列出了主要的解析器, 以及它们的优缺点(以下内容来自: ):
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python 标准库 | BeautifulSoup(markup, "html.parser") | Python 的内置标准库、执行速度适中、文档容错能力强 | Python 2.7.3 or 3.2.2) 前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快、文档容错能力强 | 需要安装 C 语言库 |
lxml XML 解析器 | BeautifulSoup(markup, ["lxml-xml"]) 、 BeautifulSoup(markup, "xml") | 速度快、唯一支持 XML 的解析器 | 需要安装 C 语言库 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性、以浏览器的方式解析文档、生成 HTML5 格式的文档 | 速度慢、不依赖外部扩展 |
推荐使用 lxml 作为解析器, 因为效率更高. 在 Python2.7.3 之前的版本和 Python3 中 3.2.2 之前的版本, 必须安装 lxml 或 html5lib , 因为那些 Python 版本的标准库中内置的 HTML 解析方法不够稳定.
提示: 如果一段 HTML 或 xml 文档格式不正确的话, 那么在不同的解析器中返回的结果可能是不一样的, 查看 解析器之间的区别 了解更多细节.
基本操作
爬取对象还是小编的个人博客(小编看着博客的流量在暗暗心痛). 最基本的, 还是先打印首页的 HTML 源码, 使用的类库为 Requests + bs4.
- import requests
- from bs4 import BeautifulSoup
- response = requests.get('https://www.geekdigging.com/')
- soup = BeautifulSoup(response.content, "html5lib")
- print(soup.prettify())
结果就不贴了, 太长, 浪费大家翻页的时间.
首先先解释一下这里为什么选择了 html5lib 的解析器而不是 lxml 的解析器, 因为经过小编测试 lxml 的解析器无法解析某些 HTML 标签, 经过小编的测试, 使用 Python 标准库或者 html5lib 解析器都无此问题, 所以这里选择使用 Python 标准库.
上面这段代码主要是调用了 prettify() , 这个方法的主要作用是把要解析的字符串以标准的缩进格式输出. 值得注意的是, 这里的输出会自动更正 HTML 的格式, 但是这一步并不是由 prettify() 这个方法来做的, 而是在初始化 BeautifulSoup 时就完成了.
节点选择
我们使用 Beautiful Soup 的目的是什么? 当然是要选择我们需要的节点, 并从节点中提取出我们需要的数据.
Beautiful Soup 将复杂 HTML 文档转换成一个复杂的树形结构, 每个节点都是 Python 对象, 所有对象可以归纳为 4 种: Tag , NavigableString , BeautifulSoup , Comment .
我们直接调用节点的名称就可以选择节点元素, 再调用 string 属性就可以得到节点内的文本了, 这种选择方式速度非常快.
- print(soup.title)
- print(type(soup.title))
- print(soup.title.string)
- print(soup.a)
结果如下:
- <title>
- 极客挖掘机
- </title>
- <class 'bs4.element.Tag'>
极客挖掘机
- <a class="logo" href="/">
- <img src="/favicon.jpg" style="margin-right: 10px;" />
- 极客挖掘机
- </a>
可以看到, 我们这里直接输出的 title 节点, 它的类型是 bs4.element.Tag , 并且使用 string 属性, 直接得到了该节点的内容.
这里我们打印了 a 节点, 可以看到, 只打印出来了第一个 a 节点, 后面的节点并未打印, 说明当有多个节点时, 这种方式只能获得第一个节点.
获取名称
每个 tag 都有自己的名字, 通过 .name 来获取:
- tag = soup.section
- print(tag.name)
结果如下:
section
获取属性
一个 tag 可能有很多个属性, tag 的属性的操作方法与字典相同:
print(tag['class'])
结果如下:
['content-wrap']
也可以直接 "点" 取属性, 比如: .attrs :
print(tag.attrs)
结果如下:
{'class': ['content-wrap']}
获取内容
可以利用 string 属性获取节点元素包含的文本内容, 比如要获取 title 标签的内容:
print(soup.title.string)
结果如下:
极客挖掘机
嵌套选择
- print(soup.a.img)
- print(type(soup.a.img))
- print(soup.a.img.attrs)
- <img src="/favicon.jpg" style="margin-right: 10px;" />
- <class 'bs4.element.Tag'>
- {'src': '/favicon.jpg', 'style': 'margin-right: 10px;'}
- for child in enumerate(soup.article.children):
- print(child)
- for i, child in enumerate(soup.article.descendants):
- print(i, child)
- print('next_sibling:', soup.title.next_sibling)
- print('previous_sibling:', soup.title.previous_sibling)
- print('next_siblings:', soup.title.next_siblings)
- print('previous_siblings:', soup.title.previous_siblings)
- next_sibling:
- previous_sibling:
- next_siblings: <generator object PageElement.next_siblings at 0x00000183342C5D48>
- previous_siblings: <generator object PageElement.previous_siblings at 0x00000183342C5D48>
来源: https://www.cnblogs.com/babycomeon/p/12057994.html