第-4章-用-CSV-和-Excel-存储数据

第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/']

使用此类脚本下载网站内容时应遵守网站的使用条款,以及相关的法律法规。
本系列文章皆做为学习使用,勿商用。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Vue中的el-table组件是一个强大的表格组件,它可以方便地展示大量数据,并且支持分页功能。同时,借助前端库file-saver,我们可以实现将el-table中的数据导出为Excel文件。 要实现这个功能,首先需要在Vue项目中安装file-saver库。可以使用npm或者yarn命令进行安装。 安装完毕后,我们可以在需要导出Excel的页面中引入file-saver库。 import { saveAs } from 'file-saver'; 在el-table的数据源中,我们通常会使用一个数组来存储表格的数据。假设我们的表格数据为tableData,我们可以通过将这个数组转换为Excel文件来实现导出功能。 首先将表格数据转换为二维数组的形式,使得每一行的数据存储在一个小数组中。 const exportData = tableData.map(row => { return Object.values(row); }); 然后,我们可以使用file-saver库提供的saveAs函数来将数据导出为Excel文件。我们需要将二维数组导出为一个csv格式的文本文件,并使用saveAs函数保存文件。 const csvContent = exportData.map(row => row.join(",")).join("\n"); const blob = new Blob(["\ufeff" + csvContent], { type: "text/csv;charset=utf-8" }); saveAs(blob, "export.csv"); 在上述代码中,我们首先将二维数组通过map和join方法转换为一个csv格式的字符串,然后使用Blob创建一个Blob对象,最后使用saveAs函数将Blob对象保存为一个名为export.csv的文件。 通过上述步骤,我们就可以实现在Vue中使用file-saver库将el-table中的分页数据导出为Excel文件。导出的文件可以方便地在Excel中查看和处理。 ### 回答2: Vue的el-table组件和FileSaver,可以实现前端导出Excel并导出分页数据的功能。 首先,我们需要引入el-table和FileSaver库,并确保已经正确配置了Vue项目。然后,在组件中使用el-table,并将分页数据绑定到el-table的data属性上。 接下来,我们需要添加一个导出按钮,用于触发导出操作。当按钮被点击时,我们可以通过el-table的方法将分页数据转换为一个二维数组,并使用FileSaver库将该数组导出为Excel文件。 具体实现步骤如下: 1. 引入el-table和FileSaver库: ``` import FileSaver from 'file-saver'; import { ElTable, ElTableColumn } from 'element-ui'; ``` 2. 在组件中使用el-table,并将分页数据绑定到data属性上: ``` <template> <el-table :data="tableData"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> ... </el-table> </template> <script> export default { data() { return { tableData: [], // 分页数据 ... }; }, ... }; </script> ``` 3. 添加一个导出按钮,并在按钮的点击事件中执行导出操作: ``` <template> <el-table :data="tableData"> ... </el-table> <el-button @click="exportExcel">导出Excel</el-button> </template> <script> export default { ... methods: { exportExcel() { const data = this.$refs.table.store.states.data; // 获取所有数据 const columns = this.$refs.table.columns.map(column => column.label); // 获取表头 const tableData = [columns, ...data]; // 构造二维数组 const worksheet = XLSX.utils.aoa_to_sheet(tableData); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const blob = new Blob([excelBuffer], { type: 'application/octet-stream' }); FileSaver.saveAs(blob, 'data.xlsx'); }, ... } }; </script> ``` 以上代码通过el-table的$refs属性获取到el-table的实例,从而可以获取到所有数据和表头,并进行导出操作。最后使用FileSaver库将二维数组保存为Excel文件,文件名为data.xlsx。 通过以上步骤,我们可以实现vue el-table前端导出Excel并导出分页数据的功能。 ### 回答3: 在使用vue el-table和file-saver前端库导出Excel时,默认情况下只会导出当前展示页面的数据,无法导出分页数据。但我们可以通过以下步骤来实现导出分页数据的功能。 首先,我们需要手动获取所有需要导出的数据。可以通过向后端发送请求获取所有数据的接口,并在前端将返回的数据进行合并。 然后,使用file-saver库将合并后的数据导出为Excel文件。可以使用Blob对象将数据转换为二进制文件,再通过saveAs方法将二进制文件保存为Excel文件。 最后,展示给用户下载链接或直接自动下载导出的Excel文件。 这样,我们就可以实现使用vue el-table和file-saver前端库导出分页数据的功能。 需要注意的是,如果数据量较大,一次性获取全部数据可能会影响前端性能和用户体验。因此,可以考虑在导出功能中添加限制,例如设置最大导出数量或者提供导出当前页和导出全部数据的选项供用户选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值