第4章 用 CSV 和 Excel 存储数据

4.1 用 CSV 文件存储数据

CSV(Comma-Separated Values)其实就是纯文本,用逗号分隔值,可以分隔成多个单元格。CSV 文件除了可以用普通的文本编辑工具打开,还能用 Excel 打开,但 CSV 和 Excel

有以下不同:

  • 所有值都是字符串类型。
  • 不支持设置字体颜色和样式。
  • 不能指定单元格宽、高或合并单元格。
  • 没有多个工作表。
  • 不能嵌入图片、图表。

Python 中内置了一个 csv 模块用来处理 CSV 文件。

4.1.1 CSV 写入

csv 模块提供了两个写入的函数。

  • writerow:写入一行。
  • writerows:写入多行。

使用代码示例如下:

import csv
import os # 定义要保存的文件名
save_file_name_1 = os.path.join(os.getcwd(), '1.csv')
save_file_name_2 = os.path.join(os.getcwd(), '2.csv') # 定义要写入的数据
data_1 = [
['id', '姓名', '性别', '年龄', '工作'],
[1, '小明', '男', '18', '学生'],
[2, '小红', '女', '24', '老师'],
[3, '小光', '男', '25', 'Python工程师']
] # 单行写入示例
with open(save_file_name_1, 'w', newline='') as f:
writer = csv.writer(f)
for row in data_1:
writer.writerow(row) # 多行写入示例
with open(save_file_name_2, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerows(data_1)

上面的 newline=''参数,如果不设置的话,每写入一行后将会写入一个空行。除了用writer 函数,还可以用 DictWriter 写入字典形式的数据,代码示例如下:

import csv
import os # 定义要保存的文件名
save_file_name_3 = os.path.join(os.getcwd(), '3.csv') # 定义列标题和数据
headers = ['id', '姓名', '性别', '年龄', '工作']
data_2 = [
{'id': 1, '姓名': '小明', '性别': '男', '年龄': '18', '工作': '学生'},
{'id': 2, '姓名': '小红', '性别': '女', '年龄': '24', '工作': '老师'},
{'id': 3, '姓名': '小光', '性别': '男', '年龄': '25', '工作': 'Python工程师'}
] # 字典写入
with open(save_file_name_3, 'w', newline='') as f:
# 使用DictWriter创建writer对象,headers传入以定义列标题
writer = csv.DictWriter(f, fieldnames=headers)
# 写入表头
writer.writeheader()
# 循环遍历数据列表,每次写入一行
for row in data_2:
writer.writerow(row)

以上代码执行后生成的 CSV 内容如下所示:

id,姓名,性别,年龄,工作
1,小明,男,18,学生
2,小红,女,24,老师
3,小光,男,25,Python工程师

4.1.2 CSV 读取

通过调用 csv.reader()函数获得一个可迭代对象,此对象只能迭代一次,不能直接打印,可以用 list()将其转换为列表,示例如下:

with open(save_file_name_1) as f:
reader = csv.reader(f)
print(list(reader))

代码执行结果如下:

[['id', '姓名', '性别', '年龄', '工作'], ['1', '小明', '男', '18', '学生'], ['2', '小红', '女', '24', '老师'], ['3', '
小光', '男', '25', 'Python工程师']]

除此之外,还有以下几种读取元素的方法:

# 直接通过下标获取
print(list(reader)[0][1])
# reader.line_num用于获取行号
for row in reader:
print(reader.line_num, row)
# 除此之外,由于reader是可迭代对象,可以使用next方法一次获取一行
head_row = next(reader)

代码执行结果如下:

1 ['id', '姓名', '性别', '年龄', '工作']
2 ['1', '小明', '男', '18', '学生']
3 ['2', '小红', '女', '24', '老师']
4 ['3', '小光', '男', '25', 'Python工程师']

另外,还可以使用 DictReader,像操作字典那样获取数据,把表的首行(表头)作为key,访问每行中对应 key 的数据,代码示例如下:

with open(save_file_name_1) as f:
reader = csv.DictReader(f)
for row in reader:
print(row['姓名'])

代码执行结果如下:

小明
小红
小光

4.2 实战:爬取星座运势

我们通过一个例子来巩固 csv 库的使用,爬取的站点为 http://www.xzw.com/fortune/

上面就是我们想爬取的内容,采集的数据格式是:星座—生日时间—运势评分—今日运势,我们来分析网页的目录结构。

接下来编写代码来解析对应的节点。

import csv
import requests
from lxml import etree # 准备CSV文件
with open('fortune_data.csv', mode='w', encoding='utf-8', newline='') as file:
writer = csv.writer(file)
# 写入表头
writer.writerow(['星座', '时间', '综合运势', '爱情运势', '事业学业', '财富运势',
'健康运势']) base_url = 'https://www.xzw.com/fortune/'
resp = requests.get(base_url)
html = etree.HTML(resp.text)
titles = html.xpath('//*[@id="list"]/div[1]/div/dl/dd/strong/text()')
sjs = html.xpath('//*[@id="list"]/div[1]/div/dl/dd/small/text()')
xz_urls = html.xpath('//*[@id="list"]/div[1]/div/dl/dd/p/a/@href') for title, sj, xz_url in zip(titles, sjs, xz_urls):
xz_url = xz_url.split('/')[2]
url = base_url + xz_url
response = requests.get(url)
content = etree.HTML(response.text)
p1 = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[1]/strong/text()')
p1_txt = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[1]/span/text()')
p2 = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[2]/strong/text()')
p2_txt = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[2]/span/text()')
p3 = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[3]/strong/text()')
p3_txt = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[3]/span/text()')
p4 = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[4]/strong/text()')
p4_txt = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[4]/span/text()')
p5 = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[5]/strong/text()')
p5_txt = content.xpath('//*[@id="view"]/div[2]/div[3]/div[2]/p[5]/span/text()') # 将数据整合为一行
row = [title, sj]
for txt in zip(p1_txt+p2_txt+p3_txt+p4_txt+p5_txt):
row.append(''.join(txt)) # 将文本列表转换为字符串 # 写入CSV
writer.writerow(row)

代码执行后生成的文件里的内容如下:

星座,时间,综合运势,爱情运势,事业学业,财富运势,健康运势
白羊座,3.21-4.19,整体运势并不是很好,会感到自己没有太多的主导权,容易被他人牵着鼻子走。你可能会遇到一些挫折或阻碍,感到事事不顺心。建议保持冷静,不要冲动行事,避免做出错误的决策。尽量与身边的人保持良好的沟通,以避免产生误解或冲突。在生活方面,适合参加一些放松身心的活动,如瑜伽或冥想,平复情绪,调整自己的状态。,单身的感情运势不太好,你可能会因为过于幼稚而让对方对你失去兴趣。已有伴者的也需要注意自己的言行举止,不要让伴侣觉得你不够成熟。,需要保持清醒的认知,不要被琐事和情绪困扰。目前你可能会感觉进展缓慢,但这是一个耕耘的阶段。保持全力以赴的姿态稳步前行,不要过分追求速度。,财务状况基本保持现状。建议你继续保持理性和节制,不要盲目冲动消费或进行大额投资。保持现有的财务计划和支出,稳健管理财务,避免冲动行为。,注意不要沉迷手机。过度使用手机会导致眼睛疲劳和颈椎问题。记得多休息眼睛,每小时眺望远处5分钟,同时做些颈部伸展运动。保持适当的手机使用时间,对眼睛和颈椎都有好处。
...

4.3 用 Excel 文件存储数据

Excel 相比 CSV 功能会多一些,比如支持设置字体颜色和样式,而 Python 操作 Excel可以用两个库:xlwt(写 Excel) 和 xlrd(读Excel),可以通过 pip 命令直接安装:

pip install xlwt
pip install xlrd

4.3.1 Excel 写入

xlwt 库中有关写入的函数如下所述。

  • xlwt.Workbook():创建一个工作簿。
  • 工作簿对象.add_sheet(cell_overwrite_ok=True):添加工作表,括号里是可选参数,用于确认同一个 cell(单元)是否可以重设值。
  • 工作表对象.write(行号,列号,插入数据,风格):第四个参数可选。
  • 工作簿对象.save(Excel 文件名):保存到 Excel 文件中。

写入代码示例如下:

import xlwt
import xlrd
import os
# 新建一个工作簿
workbook = xlwt.Workbook()
sheet = workbook.add_sheet('工作表1',cell_overwrite_ok=True)
sheet.write(0, 0, '姓名')
sheet.write(0, 1, '学号')
sheet.write(1, 0, '小猪')
sheet.write(1, 1, '1')
workbook.save(os.path.join(os.getcwd(), 'result.xlsx'))

代码执行后生成的列表结构如下:

姓名 学号
小猪 1

4.3.2 Excel 读取

xlrd 库中有关读取的函数如下所述。

  • xlrd.open_workbook():读取一个 Excel 文件,获得一个工作簿对象。
  • 工作簿对象.sheets()[0]:根据索引获得工作簿里的一个工作表。
  • 工作表对象.nrows:获得行数。
  • 工作表对象.ncols:获得列数。
  • 工作表对象.row_values(pos):读取某一行的数据,返回的结果是列表类型。

读取代码示例如下:

import xlrd
workbook = xlrd.open_workbook(os.path.join(os.getcwd(), 'result.xlsx'))
sheet = workbook.sheets()[0]
# 获得行数
row_count = sheet.nrows
for row in range(0, row_count):
print(sheet.row_values(row))

代码执行结果如下:

['姓名', '学号']
['小猪', '1']

4.4 实战:爬取某音乐平台排行榜

我们通过一个例子来巩固 xlwt 库和 xlrd 库的使用,爬取的站点为 https://music.douban.com/top250

爬取第一页

import requests
from lxml import etree
import xlwt
import re
# 初始化请求信息
url = 'https://music.douban.com/top250'
headers = {
'Host': 'music.douban.com',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
} # 发送请求获取HTML内容
response = requests.get(url, headers=headers)
html = etree.HTML(response.text) # 使用XPath解析所需数据
song_names = html.xpath('//td[2]/div/a/text()')
song_imgs = html.xpath('//td[1]/a/img/@src')
singer_names = html.xpath('//td[2]/div/p/text()')
rating_nums = html.xpath('//td[2]/div/div/span[2]/text()')
rating_people = html.xpath('//td[2]/div/div/span[3]/text()')
music_hrefs = html.xpath('//td[2]/div/a/@href') # 创建Excel工作簿和工作表
workbook = xlwt.Workbook()
sheet = workbook.add_sheet('豆瓣音乐Top250', cell_overwrite_ok=True) # 写入表头
columns = ['歌曲名', '封面图片链接', '歌手', '发行时间', '类型', '评分', '评价人数', '详情链接']
for i, column in enumerate(columns):
sheet.write(0, i, column) # 遍历数据并写入
row = 1
for song_name, song_img, singer_message, rating_num, rating_people, music_href in zip(song_names, song_imgs, singer_names, rating_nums, rating_people, music_hrefs):
song_name = song_name.strip()
singer_name = singer_message.split('/')[0].strip()
song_time = singer_message.split('/')[1].strip()
type = '/'.join(singer_message.split('/')[2:]).strip()
rating_num = rating_num.strip()
match = re.search(r'\d+', rating_people)
if match:
number = match.group() data = [song_name, song_img, singer_name, song_time, type, rating_num, number+'人评价', music_href]
for i, value in enumerate(data):
sheet.write(row, i, value)
row += 1 # 保存到当前目录下的Excel文件
workbook.save('douban_music_top250.xls')

爬取全部

import requests
from lxml import etree
import xlwt
import re # 创建Excel工作簿和工作表
workbook = xlwt.Workbook()
sheet = workbook.add_sheet('豆瓣音乐Top250', cell_overwrite_ok=True) # 写入表头
columns = ['歌曲名', '封面图片链接', '歌手', '发行时间', '类型', '评分', '评价人数', '详情链接']
for i, column in enumerate(columns):
sheet.write(0, i, column) row = 1 # 初始化行号 # 循环遍历每一页
for page in range(0, 250, 25):
url = f'https://music.douban.com/top250?start={page}'
headers = {
'Host': 'music.douban.com',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
} response = requests.get(url, headers=headers)
html = etree.HTML(response.text) song_names = html.xpath('//td[2]/div/a/text()')
song_imgs = html.xpath('//td[1]/a/img/@src')
singer_names = html.xpath('//td[2]/div/p/text()')
rating_nums = html.xpath('//td[2]/div/div/span[2]/text()')
rating_people = html.xpath('//td[2]/div/div/span[3]/text()')
music_hrefs = html.xpath('//td[2]/div/a/@href') for song_name, song_img, singer_message, rating_num, rating_people, music_href in zip(song_names, song_imgs, singer_names, rating_nums, rating_people, music_hrefs):
song_name = song_name.strip()
singer_name = singer_message.split('/')[0].strip()
song_time = singer_message.split('/')[1].strip()
type = '/'.join(singer_message.split('/')[2:]).strip()
rating_num = rating_num.strip()
match = re.search(r'\d+', rating_people)
if match:
number = match.group() data = [song_name, song_img, singer_name, song_time, type, rating_num, number + '人评价', music_href]
for i, value in enumerate(data):
sheet.write(row, i, value)
row += 1 # 更新行号以便写入下一行 # 保存到当前目录下的Excel文件
workbook.save('douban_music_top250.xls')

读取 Excel

import xlrd

def read_data():
xlsx = xlrd.open_workbook('douban_music_top250.xls')
table = xlsx.sheets()[0]
nrows = table.nrows # 行数
ncols = table.ncols # 列数
# 从第二行开始,因为第一行是表头
for i in range(1, nrows):
row_value = table.row_values(i)
print(row_value)
# 调用函数
read_data()

显示 Console 的部分结果如下:

['We Sing. We Dance. We Steal Things.', 'https://img3.doubanio.com/view/subject/s/public/s2967252.jpg', 'Jason Mraz', '2008-05-13', 'Import / Audio CD / 民谣', '9.1', '116284人评价', 'https://music.douban.com/subject/2995812/']

使用此类脚本下载网站内容时应遵守网站的使用条款,以及相关的法律法规。

本系列文章皆做为学习使用,勿商用。

第 4章 用 CSV 和 Excel 存储数据的更多相关文章

  1. 14、使用csv和excel存储豆瓣top250电影信息

        记得我们第三关的时候爬取了豆瓣TOP250的电影名/评分/推荐语/链接,现在呢,我们要把它们存储下来,记得用今天课上学的csv和excel,分别存储下来哦-       URL     htt ...

  2. Python 编程快速上手 第十四章 处理 CSV 文件和 JSON 数据

    前言 这一章分为两个部分,处理 CSV 格式的数据和处理 JSON 格式个数据. 处理 CSV 理解 csv csv 的每一行代表了电子表格中的每一行,每个逗号分开两个单元格csv 的内容全部为文本, ...

  3. Pandas系列-读取csv/txt/excel/mysql数据

    本代码演示: pandas读取纯文本文件 读取csv文件 读取txt文件 pandas读取xlsx格式excel文件 pandas读取mysql数据表 import pandas as pd 1.读取 ...

  4. Unity 读取CSV与Excel

    前几天看到我们在游戏中需要动态加载某些角色的游戏策划值,关于这个问题怎么解决呢?其实办法很多种,归根到底,就是数据的读取.我们可以想到的存储数据的载体有很多.例如:txt,xml,csv,excel. ...

  5. 15、解决14中csv用excel打开乱码的问题 open('zhihu.csv','w',newline='',encoding='utf-8-sig')

    解决14中csv用excel打开乱码的问题 ,其实就是在写csv的时候把 utf-8 改成 utf-8-sig open('zhihu.csv','w',newline='',encoding='ut ...

  6. R—读取数据(导入csv,txt,excel文件)

    导入CSV.TXT文件 read.table函数:read.table函数以数据框的格式读入数据,所以适合读取混合模式的数据,但是要求每列的数据数据类型相同. read.table读取数据非常方便,通 ...

  7. 第十七篇:csv拆分、csv转excel方法

    首先对微软的office功能表示敬佩!可能是这些办公软件太过平常化,所以体会不到他有多牛!csv格式数据以前没接触过,百度百科定义,Comma-Separated Values,CSV,逗号分隔值,或 ...

  8. python读取csv,Excel,Txt,Yaml 文件

    1.数据 1.Csv login.csv文件: byhy,88888888 ReadCsv.py文件 import csv #导入csv包 class ReadCsv(): def csv(self) ...

  9. php使用ajax导出CSV或者EXCEl(thinkphp)方法

    首先我强烈推荐看到这篇文章的你将导出文件设置为csv格式的文件 实际测试导出csv文件的速度是excel文件的10几倍左右 首先我先介绍csv文件的导出的方法: 如果你单纯是在数据导出界面上通过用户点 ...

  10. csv,txt,excel文件之间的转换,perl脚本

    最近接触一些需要csv,txt,excel文件之间的转换,根据一些网上搜索加上自己的改动,实现自己想要的结果为主要目的,代码的出处已经找不到了,还请见谅,以下主要是针对csv&excel 和t ...

随机推荐

  1. CYQ.Data 操作 Redis 性能测试:对比 StackExchange.Redis

    前言: 前几天,点开自己的博客,看了一下 CYQ.Data V5系列 都有哪些文章, 发现了一篇2019年写的:CYQ.Data 对于分布式缓存Redis.MemCache高可用的改进及性能测试,于是 ...

  2. 21_显示YUV图片&视频

    一.显示YUV图片 显示 YUV 图片和显示 BMP 图片的大致流程是一样的.显示 BMP 图片我们可以直接获取到 BMP 图片的 surface,然后直接从 surface 创建纹理.显示 YUV ...

  3. Django 使用 Nginx + uWSGI 启动

    一.前言 购买了腾讯云服务器练习 Django 项目时, # 最开始用的启动 Django 项目命令 python3 manage.py runserver 0.0.0.0:80 后面发现我一旦把 x ...

  4. 像使用stl一样使用线段树 ——AtCoder Library(转载https://zhuanlan.zhihu.com/p/459579152)

    地址:https://zhuanlan.zhihu.com/p/459579152 我这里翻译一下官方的文档. 首先需要满足几个性质. (注意 ∗ 是个操作,不是单纯的一个乘号) 1)操作满足结合律 ...

  5. django(cookie与session、中间件、auth模块)

    一 cookie与session 1 发展史及简介 """ 发展史 1.网站都没有保存用户功能的需求,所有用户访问返回的结果都是一样的 eg:新闻.博客.文章 2.出现了 ...

  6. MySQL(视图、事务、存储过程、函数、流程控制、索引)

    一 视图(了解) 什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次可以直接使用 为什么要用视图 如果要频繁的操作一张虚拟表(拼表组成的),你就可以制作成视图,后续直接操作 视图其实也是一 ...

  7. linux 安装mysql8.0.11

    1.使用系统的root账户 2.切换到/use/local 目录下 3.下载mysql ?wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysq ...

  8. KingbaseES V8R6 等待事件之IO类BufFileRead BufFileWrite

    等待事件含义 当数据库创建临时文件时,会发生IO:BufFileRead和IO:BufFileWrite等待事件.当操作需要的内存比当前定义的work_mem内存参数更多时,会将临时数据写入磁盘永久存 ...

  9. S7Comm报文详解

    S7协议是西门子公司为其S7系列PLC(可编程逻辑控制器)通信而设计的一种专用协议.S7协议主要用于西门子PLC之间的通信,以及PLC与其他设备的通信.该协议支持多种通信方式,如MPI(多点接口).P ...

  10. #排序,去重#洛谷 5682 [CSPJX2019]次大值

    题目 分析 首先,显然要排序去重,考虑最大值应该是\(a_{n-1}\)(排序后) 那次大值只有可能出现在\(a_{n-2}\)或者\(a_n\bmod a_{n-1}\)中 当然去重后如果只有一个数 ...