- Python3网络爬虫宝典
- 韦世东
- 3102字
- 2021-03-31 21:34:49
1.5 数据存储
顺利地发出网络请求并从响应正文中提取出想要的内容后,便要考虑如何将内容保存起来。数据的存储方式通常由需求方决定,如果需求方没有指定存储方式,则由爬虫工程师自己选择。
文字类数据通常存储在数据库中,例如MySQL数据库、MongoDB数据库或者Redis数据库。文件存储在服务器硬盘中,再将存储路径存储到数据库里。商品类数据或者后续用于分析的数据通常会存储在CSV或者xls文件中。将数据存储在文本文件中的情况比较少,但也不能忽略。
本节我们将学习如何将文字类数据存储到数据库中,如何存储文件类数据,如何将数据存储到xls文件中。
1.5.1 将数据存入MySQL数据库
MySQL是一款免费的关系型数据库,它免费且简单易用的特点使得它深受开发者的喜爱。Python连接或操作MySQL数据库时需要使用专门的连接库,例如PyMySQL。我们可以通过PyMySQL来操作MySQL数据库,例如创建数据库、创建数据表、写入数据、读取数据和删除数据等。
在开始学习之前,请按照MySQL官方文档的指引安装MySQL数据库。接着使用Python的包管理工具安装PyMySQL库,对应的安装命令如下:
假设MySQL中有一个名为books的数据库,数据库里有一张名为ranking的数据表,其内容如表1-3所示。
表1-3 数据表ranking内容示意
接下来我们将围绕这张数据表执行一系列操作,以了解PyMySQL的基本使用方法。首先编写连接数据库的代码:
PyMySQL提供了execute()方法,我们可以将数据库操作语句以字符串的方式传入,包括查询语句、更新语句和删除语句等。查询数据表ranking中所有数据的代码为:
代码执行结果如下:
执行fetchall()方法后返回了一个列表对象,列表中以字典形式存储着数据库中的行数据。假设我们需要逐条打印书籍信息,那么我们可以用 for 循环,对应的代码为:
代码运行结果如下:
假设我们需要更新《Python3反爬虫原理与绕过实战》的价格,对应语句为:
这段代码执行后并不会输出或打印结果,要想查看结果我们可以再次执行上一次的查询代码和循环代码,代码运行结果如下:
图书《Python3反爬虫原理与绕过实战》的价格由89.0变成了66.7,说明更新语句执行成功。假设我们从网页提取的数据存放在对象data中,那么将data逐一添加到数据库的代码为:
代码运行后,数据库中的数据如下:
这说明数据已经存入了数据库中。以上就是使用PyMySQL操作MySQL数据库的基本方法,更多知识请翻阅PyMySQL官方文档。
1.5.2 将数据存入MongoDB数据库
MongoDB是一款基于分布式文件存储的非关系型数据库。MongoDB数据库不需要提前设置字段名称和对应的类型,使用时直接写入即可。同一个集合可以存储不同结构的文档,就算缺少字段也不会影响数据的写入。这两个特点正是它成为最受爬虫工程师欢迎的数据库的原因。
Python连接或操作MongoDB数据库时需要使用专门的连接库,例如PyMongo。我们可以通过PyMongo来操作MongoDB数据库,例如创建数据库、创建集合、写入文档、读取文档和删除文档等。
在开始学习之前,请按照MongoDB官方文档的指引安装MongoDB数据库。接着使用Python的包管理工具安装PyMongo库,对应的安装命令如下:
由于MongoDB不需要提前建立数据库和集合,所以我们可以在代码中指定任意名称的数据库和集合。首先编写连接数据库的代码,并指定数据库名为books,指定集合名称为ranking:
假设我们从网页提取的数据存放在对象data中,那么将data添加到数据库的代码为:
从MongoDB中查询数据也很简单,代码如下:
代码运行结果如下:
这里的_id是MongoDB自动为文档生成的唯一ID。当我们想要从数据库中查询指定的数据时,可以指定_id或者指定查询条件,例如查询价格大于50.0的书籍信息:
代码运行结果如下:
假设我们需要将图书《Go语言核心编程》的状态改为ON,则对应的代码如下:
代码运行结果如下:
运行结果说明我们已经成功地修改了图书《Go语言核心编程》的状态。熟悉MongoDB的读者会发现,PyMongo的语法与MongoDB原生语法十分接近,包括条件筛选、联合查询和删除操作。这样的设计减少了使用者的学习成本,这也是PyMongo库深受爬虫工程师欢迎的原因之一。
以上就是PyMongo操作MongoDB数据库的基本方法,更多知识请翻阅PyMongo官方文档。
1.5.3 将数据存入Redis数据库
Redis是目前流行的且性能极高的Key-Value数据库,爬虫工程师在设计分布式爬虫架构时通常会将Redis考虑到其中。与MySQL和MongoDB数据库相同的是,Python连接或操作Redis数据库时也需要使用专门的连接库,例如redis库。我们可以通过redis库来操作Redis数据库,例如创建集合、写入数据、读取数据和删除数据等。
在开始学习之前,请按照Redis官方文档的指引安装Redis数据库。接着使用Python的包管理工具安装redis库,对应的安装命令如下:
首先编写连接数据库的代码:
假设我们需要在Redis数据库中新建一个名为ranking的集合,并将爬虫爬取到的书籍信息写入到ranking中,对应的代码如下:
查询Redis数据库中ranking集合数据的代码为:
代码运行结果如下:
假设我们需要查询集合中存储了多少条数据,可以用SCARD命令,对应的代码如下:
输出结果为3。
在实际的爬虫程序编写过程中,我们很有可能遇到这样的一种需求:数据条数满100条时存储1次,以达到降低数据库I/O消耗的目的。这种需求我们可以借助redis库提供的pipeline()方法实现,对应的代码为:
待写入数据总数为1008条,每100条写入1次。考虑到剩下的8不满足100条的条件,遂在for循环外再调用一次execute()方法。代码运行后,Redis数据库中ranking集合的数据条数如下:
之前有3条数据,加上这次写入的1008条,共1011条,说明数据已经成功写入Redis数据库中。
跟PyMongo语法和MongoDB语法的关系一样,redis库的语法与Redis数据库原生语法也十分接近,只要了解Redis数据库的语法,一定能够快速掌握redis库的基本用法。
以上就是使用redis库操作Redis数据库的基本方法,更多知识请翻阅redis库的官方文档。
1.5.4 Excel文件的读写
Python对文件的读写有着原生的支持,我们只需要调用内置的open()函数或者使用上下文管理器with open()的方式创建一个文件并将内容写入即可。我们可以将str格式的文字写入到文本文件中,也可以将图片的bytes数据以wb模式写入到文件中,并用.png或.jpg等作为文件后缀。图片爬取和存储的代码片段如下:
代码逻辑很简单,导入Requests库后调用get()方法向电子工业出版社官网LOGO图片的网址发出请求,然后提取bytes格式的响应信息,接着创建一个名为logo、后缀为.jpg的文件,并将bytes格式的响应信息写入文件。代码运行后,logo.jpg文件就会生成,图片如图1-32所示。
图1-32 logo.jpg
如果想要将数据按照一定格式存入Excel文档对应的xls文件中,可就没那么简单了。Python官方并不支持特定的文件格式,我们需要借助其他开发者编写的库向Excel文档写入数据或者从Excel文档中读取数据。Python开发者用得最多的Excel库分别是xlwt和xlrd,其中xlwt用于向Excel文档写入数据,xlrd用于从Excel文档读取数据。我们可以使用Python的包管理工具安装这两个库,对应的安装命令如下:
根据xlwt库的文档示例,我们可以很快地写出创建Excel文档、向文档指定的行和指定的列写入数据的代码。例如,创建一个名为abs.xls的文件,并在第1个Sheet的第1行第1列写入“你好”,对应的代码为:
代码运行后,我们就会在目录中找到程序创建的abs.xls文件,打开后可以看到我们成功地将“你好”写入到指定的位置。接下来我们将在这个基础上增加一些难度,例如将一个列表中的数据存入Excel文档:
这里用了for循环将列表中的数据一条一条地写入Excel文档的指定位置。代码运行后我们将在名为simple的Excel文件中看到如表1-4所示的信息。
表1-4 Excel文件内容
在第三方库的帮助下,Excel 文档的写入工作变得很轻松,相信读取工作也一样轻松。假设我们需要从simple.xls文件中读取刚才写入的数据,对应的代码为:
代码运行结果如下:
虽然成功地输出了Excel文件中的信息,但是似乎没有结构和顺序,我们试试看能不能将它们恢复成原来的结构。首先我们需要准备一个名为info的空列表,用于存放所有数据,然后再准备一个空的字典用于存放每一行不同列的数据,接着通过for循环行和for循环列将单元格中的数据取出来,并按照循环时的顺序将数据添加到字典中。我们只需要改动for循环部分的代码即可,对应改动如下:
代码运行结果如下:
运行结果说明我们成功地将Excel文档中的数据还原为存储前的格式。
以上就是使用xlwt和xlrd库读写Excel文档的基本方法,更多知识请翻阅对应的文档。