首页 > 其他分享 >第 4章 用 CSV 和 Excel 存储数据

第 4章 用 CSV 和 Excel 存储数据

时间:2024-02-07 18:22:06浏览次数:29  
标签:xpath 存储 song text Excel div CSV id row

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

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

标签:xpath,存储,song,text,Excel,div,CSV,id,row
From: https://www.cnblogs.com/zx-demo/p/18011175

相关文章

  • 43、excel快速填充序列号,删除行时序号自动跟上
    平时填充序号的做法:首先在第1、2行输入1、2,然后用手往下拖动,填充后面的行,缺点:当我删除一行时,后面的序号不会自动按顺序填充上 解决方法:1、在excel上选中A6单元格,然后左上角输入A6:A110,按【回车】键2、直接输入【=ROW()-1】,再按【ctrl+回车】键盘就可以了缺点:由于公......
  • 如何实现Vuex本地存储
    在前端开发中,Vuex是一款非常强大的状态管理工具,但是默认情况下,Vuex的数据是存储在内存中的,刷新页面后数据将会丢失。这往往会导致用户在刷新页面后需要重新登录等繁琐的操作。本篇文章将教会您如何实现Vuex的本地存储,让您的应用程序能够在刷新页面后依然保持用户的状态和数据。一、......
  • #排列组合#CF1550D Excellent Arrays
    洛谷传送门CF1550D分析对于excellent的\(a\)来说\(|a_i-i|=x\)的值是固定的,考虑枚举它一半正一半负时函数值是最大的,当\(n\)为奇数时要分为两种情况(不过可以通过杨辉三角合并)问题是,由于\(l,r\)的范围,并不能做到所有位置都能可正可负,不过不超过\(mn=\min\{1-l,r-n\}......
  • bcdedit是Windows操作系统中的一个命令行工具,用于查看和修改启动配置数据(BCD)。启动配
    bcdedit是什么bcdedit是Windows操作系统中的一个命令行工具,用于查看和修改启动配置数据(BCD)。启动配置数据存储重要的启动信息,包括启动加载程序和启动设置。这个工具主要由高级用户、系统管理员和开发人员使用,以调整与系统启动相关的各种参数。为什么使用bcdedit修改启动设置......
  • 【office编程】VB删除指定excel中行
    打开Excel中的VisualBasic编辑器,键入以下代码:SubBatchDelete()DiminputstrAsStringDimresult()AsStringDimsheet_no()AsStringDimstart_end()AsStringDimi,n,num,WS_CountAsIntegerDimwsAsWorksheetinputst......
  • MySQL存储引擎-InnoDB数据页
    MySQL存储引擎-InnoDB数据页MySQL一个数据页默认16kb,MySQL为了不同目的涉及了很多类型的数据页,如undo页、ChangeBuffer页等等。我们这里只关心存放数据的页,即索引(INDEX)页。一个数据页的存储空间大致被划分为7部分,分别为:1、FIleHeader 文件头 38字节2、PageHeader页面......
  • [office] Excel怎么设置从指定部分分页打印
    excel表格中的指定一部分数据想分成两页打印,该怎么设置呢?下面就跟小编一起看看吧。Excel设置从指定部分分页打印的步骤1、现有如下字段:按班级进行打印。一班的同学打印在一张纸上。二班的同学打印在一张纸上!2、点击视图菜单下面的分页预览3、选择要分割的......
  • SAN和NAS存储
    SAN:是一种高速网络架构,用于连接存储设备(如磁盘阵列、磁带库)和服务器,实现存储资源的共享和管理,(如光纤通道、iSCSI、FCoE)连接存储设备和服务器,提供块级存储访问,具有高性能、可靠性和扩展性,适合大型企业和需要高性能、共享存储的应用场景,如虚拟化、数据库等。部署方式:(linux服务......
  • 实现流程可控的镜像下载和存储(一)
    基于https实现镜像所有相关元信息的获取在弱网环境下,下载镜像很慢且容易出错,基于这个原因需要开发更加可靠且支持断点续传的镜像下载程序由于DockerHub在国内无法访问,用自己的阿里云镜像加速替代来进行测试下面以下载linux/amd64的ubuntu22.04镜像为例Authentication例中的......
  • python爬虫爬取豆瓣电影top250并写入Excel中
    importrequestsimportreimportopenpyxl#创建工作表wb=openpyxl.Workbook()ws=wb.active#调整列距forletterin['B','C']:ws.column_dimensions[letter].width=66#发送网络请求headers={"User-Agent":'Mozilla/5.0(WindowsNT10.0;Win64;x64)......