爬虫Day16-文件数据存储

前言

关于数据存储,我们之前已经讲了数据库的存储: 爬虫Day7-Mysql的那些事 ,还有 爬虫Day13-Mongodb存储

但是对于一些小型的文件,我们可以使用多种格式类型的文件保存到本地,相对于数据库来说,比较便捷。今天介绍的是有关文件数据存储的相关内容。


文本存储

将数据保存到 TXT 文本的操作非常简单,而且 TXT 文本几乎兼容任何平台,但是有个缺点就是不利于检索,所以如果对检索和数据结构要求不高,追求方便第一的话,可以采用 TXT 文本存储。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests
from pyquery import PyQuery as pq

url = 'http://www.zhihu.com/explore'

headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0'
}

html = requests.get(url,headers=headers).text # html纯文本内容
doc = pq(html)
items = doc('.explore-tab .feed-item').items()
# 所有的回答内容都包含在此div中,我们使用items()将其变成一个迭代器

for item in items: # for 遍历这个迭代器
question = item.find('h2').text() # 提问的内容
author = item.find('.author-link-line').text() # 答主
answer = pq(item.find('.content').html()).text() # 将回答的内容提取
file = open('explore2.txt', 'a', encoding='utf-8') # 创建文件句柄
file.write('\n'.join([question,author,answer])) # 将各部分内容依次写入文件
file.write('\n'+'='*50+'\n') # 分割每一个回答
file.close()

我们在上面做了以下事情:

  1. 请求网页(设置headers头部)
  2. 发出get请求,获得网页响应内容
  3. 观察网页内容,调用解析库,传入获取的html文本,生成doc对象
  4. 使用选择器进行内容匹配
  5. 写入文件(优化数据)

需要注意的是,构造文件句柄的时候,需要注意编码问题,同时,文件的处理类型也要指明(默认是“r”)



媒体文件存储

存储媒体文件的两种方式:

  1. 只获取文件 URL 链接

  2. 直接把源文件下载下来

对于爬虫来说,如果我们要爬取的东西很多,那么建议使用第一种方式。使爬虫运行得更快,耗费的流量更少,因为只要链接,不需要下载文件。

那么,如果通过URL链接,下载我们想要的媒体文件呢?


urllib的urlretrieve方法

在python3 中, urllib.request.urlretrieve 可以根据文件的 URL 下载文件:

1
2
3
4
5
6
7
8
9
10
from urllib.request import urlretrieve
from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen('http://www.pythonscraping.com')
bsObj = BeautifulSoup(html, 'lxml')
imageLocation = bsObj.find("a", {"id": "logo"}).find("img")["src"] # 获取一张图片的URL路径

result = urlretrieve(imageLocation, "logo.jpg")
print(result)

urlretrieve方法传入两个参数:

  • 下载的URL链接,以及所保存的文件名
  • 注意文件后缀名要和保存的数据相符合,例如 图片是jpg格式,那么我们传入的文件名后缀也要是 jpg 格式


Json 文件存储

Json,全称为 JavaScript Object Notation, 也就是 JavaScript 对象标记,通过对象和数组的组合来表示数据,构造简洁但是结构化程度非常高,它是一种轻量级的数据交换格式。

Python 为我们提供了简单易用的 json 库来供我们实现 Json 文件的读写操作,我们可以调用 json 库的 loads() 方法将已编码的 JSON 字符串解码为 Python 对象,可以通过 dumps()方法将 Python 对象编码成 JSON 字符串。

值得注意的是 Json 的数据需要用双引号来包围,不能使用单引号。

并且,如果存储的数据中包含中文,我们需要指定一个参数 ensure_ascii 为 False,另外规定文件输出的编码(不指定文件输出的编码会乱码)


读取Json

读取:使用 loads() 方法,将Json对象解码为 Python 对象


存储Json

调用 dumps() 方法将 Python 对象编码成 JSON 字符串。



CSV文件存储

CSV,全称叫做 Comma-Separated Values,中文可以叫做逗号分隔值或字符分隔值。通俗的讲,他就是就是以特定字符分隔的纯文本,我们可以使用 Excel 打开 .csv的文件。单调、简朴是这种文件类型的风格。

CSV的写入

  • 首先打开了一个 data.csv 文件,然后指定了打开的模式为 w,即写入,获得文件句柄。
  • 随后调用 csv 库的 writer() 方法初始化一个写入对象,传入该文件句柄,然后调用 writerow() 方法传入每行的数据即可完成写入。
  • 第一行通常是存储字段的字段名,这起到标识字段值的作用。

文件打开效果如下:



CSV的读取

  • 关于如何打开.CSV后缀的文件,并不是在 open()返回的 File 对象上调用 read()或 readlines()方法,而是将 File 对象传递给 csv.reader()函数。这将返回一个 Reader对象。我们将基于此对象进行文件读取。
  • 同时,我们可以使用 for 循环遍历出文件内容。

线上CSV

Python 的 csv 库主要是面向本地文件,就是说你的 CSV 文件得存储在你的电脑上。而我们进行网络数据采集的时候,很多文件都是在线的。不过有几种方法可以解决这个问题:

  • 手动把 CSV 文件下载到本机,然后用 Python 定位文件位置;
  • 写 Python 程序下载文件,读取之后再把源文件删除;
  • 从网上直接把文件读成一个字符串,然后转换成一个 StringIO 对象,使它具有文件的属性。

虽然前两个方法也可以用,但是既然你可以轻易地把 CSV 文件保存在内存里,就不要再下载到本地占硬盘空间了。可以直接把文件读成字符串,然后封装成*StringIO对象,让Python把它当作文件来处理,就不需要先保存成文件了。


代码实现:

  • 跟读取本地CSV 文件步骤相似,只是多了使用 StringIO( )方法将在线的CSV文件转为StringIO对象。
  • 这样就实现了线上 CSV 的文件读取,是不是很方便!



写在最后

ok了,这一篇我们介绍了关于文件存储的大部分流行技术,快快用起来吧~

朋友们,下回见啦。