数据存储是Python爬虫持久化的重要部分。本文主要介绍数据存储中非数据库版的部分,包括存储为JSON,存储为CSV,存储多媒体文件,以及爬虫过程中出现异常时的Email提醒。
Python 对 JSON 文件的操作分为编码和解码,通过 JSON 模块来实现。编码过程是把Python 对象转换成JSON对象的一个过程,常用的两个函数是 dumps和 dump 函数。两个函数的唯一区别就是dump 把Python 对象转换成JSON对象并将JSON对象通过f文件流写入文件中而dumps 则是生成了一个字符串。下面看一下 dumps 和 dump 的函数原型:
#dump 和 dumps 的函数原型:
dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True,cls=None,indent=None, separators=None,default=None, sort_keys=False, **kw)
dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,allow_nan=True,
cls=None, indent=None, separators=None,default=None, sort_keys=False, **kw)
常用参数分析:
Skipkeys
默认值是 False。如果 dict 的 keys 内的数据不是 python 的基本类型(str、unicode、int、long、float、bool、None ),设置为 False 时,就会报 TypeError 错误。此时设置成True,则会跳过这类 key。
ensure ascii
默认值 True。如果 dict 内含有非ASCII的字符,则会以类似“\uXXXX的格式显示数据,设置成 False 后,就能正常显示。
indent
非负的整型,如果是0,或者为空,则一行显示数据,否则会换行且按照indent的数量显示前面的空白,将JSON内容进行格式化显示。
separators
分隔符,实际上是 (item_separator, dict_separator)的一个元组,默认的就是(‘,’ ‘:’),这表示 dictionary 内 keys 之间用逗号“,”隔开,而key 和value 之间用冒号“:”隔开。
encoding
默认是UTF-8。设置JSON 数据的编码方式。
sort keys
将数据根据 keys 的值进行排序。
解码过程是把json 对象转换成 python 对象的一个过程常用的两个函数是 load和loads函数,区别跟 dump 和dumps 是一样的。函数原型如下:
#load 和 loads 的函数原型:
load(fp, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
loads(s, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
常用参数分析:
encoding
指定编码格式。
parse_float
如果指定,将把每一个JSON 字符串按照 float 解码调用。默认情况下这相当于float(num_str)。
parse_int
如果指定,将把每一个JSON字符串按照 int 解码调用。默认情况下相当于int(num_str)。
Python——>JSON
Python | JSON |
---|---|
dict | object |
list,tuple | array |
str,unicode | string |
int,long,float | number |
True | true |
Flase | false |
None | null |
JSON——>Python
JSON | Python |
---|---|
object | dict |
array | list |
string | unicode |
number(int) | int,long |
number(real) | float |
true | True |
false | False |
null | None |
CSV(Comma-Separated Values,逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号)是一种以纯文本形式存储表格数据(包括数字和文本)的文件格式。纯文本意味着该文件是一个字符序列,不包含二进制的数据。
CSV 文件由任意数量的记录组成,每条记录之间使用换行符分隔。每条记录由字段组成,字段之间的分隔符可以是逗号或其他字符或字符串,最常见的是逗号或制表符。通常,所有记录都具有完全相同的字段序列。以下是一个 CSV 文件示例:
ID,UserName,Password,Age,Country
1001,"giye","qiye_pass",24,"China"
1002,"Mary","Mary_pass",20,"USA"
1003,"Jack","Jack_pass",20,"USA"
将爬取到的数据存储为 CSV 文件,可以按照以下步骤进行操作:
导入 csv 库:在 Python 中,需要先导入 csv 库才能使用其中提供的功能。可以使用以下代码进行导入:
import csv
创建或打开 CSV 文件并创建 writer 对象:使用 open()
函数创建或打开一个文件,并使用 csv.writer()
创建一个 writer 对象。指定文件名和打开模式(如 'w'
表示写入模式)。
with open('data.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
这里的 'data.csv'
是你要保存数据的文件名,可以根据实际情况修改。encoding='utf-8'
是为了确保正确处理中文字符。
写入表头(可选):如果你的数据有表头(列名),可以使用 writer 对象的 writerow()
方法将表头写入文件。
header = ['ID', 'UserName', 'Password', 'Age', 'Country']
writer.writerow(header)
这里的 header
是一个包含表头信息的列表,根据实际情况修改。
逐行写入数据:使用 writerow()
方法逐行写入数据到 CSV 文件。每行数据应以列表形式提供,列表中的每个元素对应一列数据。
data = [
[1001, 'giye', 'qiye_pass', 24, 'China'],
[1002, 'Mary', 'Mary_pass', 20, 'USA'],
[1003, 'Jack', 'Jack_pass', 20, 'USA'],
]
for row in data:
writer.writerow(row)
这里的 data
是一个包含数据的列表,根据实际情况修改。可以使用爬取到的数据替换 data
。
关闭文件:写入完成后,使用 close()
方法关闭文件。
file.close()
完成以上步骤后,爬取到的数据就会以 CSV 格式保存到指定的文件中。记得根据实际情况修改文件名、表头和数据列表。
存储媒体文件主要有两种方式
参数说明:
获取文件的 URL 链接:如果你已经获取到了多媒体文件的 URL 链接,可以将链接保存到 CSV 文件中。你可以在 CSV 文件中创建一列用于存储文件的 URL 链接,每个爬取到的文件对应一行数据。
例如,假设你已经爬取到了两个多媒体文件的 URL 链接:
urls = [
'http://example.com/file1.jpg',
'http://example.com/file2.jpg'
]
然后,可以将这些链接存储到 CSV 文件中:
import csv
with open('data.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
# 写入表头(可选)
header = ['ID', 'URL']
writer.writerow(header)
# 逐行写入数据
data = [
[1001, urls[0]],
[1002, urls[1]]
]
for row in data:
writer.writerow(row)
# 关闭文件
file.close()
直接将媒体文件下载到本地:如果你希望将媒体文件保存到本地而不仅仅是存储文件的 URL 链接,可以使用 Python 的 urllib
库来进行文件下载。
例如,假设你已经获取到了多媒体文件的 URL 链接:
urls = [
'http://example.com/file1.jpg',
'http://example.com/file2.jpg'
]
然后,可以使用以下代码将这些文件下载到本地:
import urllib.request
for i, url in enumerate(urls):
filename = f'file{i+1}.jpg' # 指定本地保存路径和文件名
urllib.request.urlretrieve(url, filename)
这里使用了 urlretrieve()
函数来下载文件,将文件保存到指定的本地路径中。
请根据你的具体需求选择适合的方式来存储爬取到的多媒体文件。注意根据实际情况调整文件名、URL 链接和本地保存路径。
Email 主要起到提醒作用,当爬虫在运行过程中遇到异常或者服务器遇到问题,可以通过 Email 及时向自己报告。发送邮件的协议是STMP,Python 内置对 SMTP 的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。Python对SMTP 支持有 smtplib 和email 两个模块。email负责构造邮件,smtplib 负责发送邮件。
首先,需要申请一个电子邮箱账号,并开启该账号的SMTP功能。接下来,可以使用smtplib模块连接到SMTP服务器,并使用邮箱账号和密码进行身份验证。然后,使用email模块构建邮件内容,可以是纯文本邮件、HTML邮件,甚至带附件的邮件。最后,通过smtplib模块发送邮件。
需要注意的是,在发送邮件之前,需要了解电子邮箱提供商的SMTP服务器地址、端口号以及所需的加密方式(如TLS或SSL等)。
具体代码示例如下:
import smtplib
from email.mime.text import MIMEText
def send_email():
host = 'smtp.example.com' # SMTP服务器地址
port = 587 # SMTP服务器端口号(根据实际情况填写)
# 邮箱登录信息
username = '[email protected]'
password = 'your_password'
# 构建邮件内容
subject = '爬虫异常提醒'
content = 'Python爬虫运行遇到异常,请及时处理!'
msg = MIMEText(content, 'plain', 'utf-8')
msg['Subject'] = subject
msg['From'] = username
msg['To'] = '[email protected]' # 收件人邮箱地址
try:
# 连接SMTP服务器
server = smtplib.SMTP(host, port)
server.starttls() # 启用TLS加密(根据实际情况选择是否启用)
server.login(username, password) # 登录邮箱账号
# 发送邮件
server.sendmail(username, [msg['To']], msg.as_string())
server.quit()
print('邮件发送成功')
except Exception as e:
print('邮件发送失败:', str(e))
# 调用函数发送邮件
send_email()