Python 文件读取

1、CSV 文件存储

1.1 写入

简单示例

import csv

with open('data.csv', 'a') as csvfile:
    writer = csv.writer(csvfile)       # 初始化写入对象,传入文件句柄
    writer.writerow(['id', 'name', 'age'])      # 调用 writerow() 方法传入每行的数据
    writer.writerow(['1', 'rose', '18'])
    writer.writerow(['2', 'john', '19'])

以文本方式打开,分隔符默认为逗号(,):

id,name,age

1,rose,18

2,john,19

修改默认分隔符:

writer = csv.writer(csvfile, delimiter=' ')   	# 以空格为分隔符

同时写入多行:

# 此时参数为二维列表
writer.writerow([['1', 'rose', '18'], ['2', 'john', '19']])

避免出现空行,可以在写入时加 newline=''

with open("test.csv", "a+", newline='') as csvfile:

如果数据源是字典

import csv

with open('data1.csv', 'a') as csvfile:
    fieldnames = ['id', 'name', 'age']      # 定义表头
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)         # 初始化一个字典,将文件句柄和表头传入
    writer.writeheader()        # 写入表头
    writer.writerow({'id': '1', 'name': 'rose', 'age': 18})     # 写入表格中具体内容

编码问题,需要指定 open() 函数编码格式:

open('data.csv', 'a', encoding='utf-8')

另外 pandas 库的 DataFrame 对象的 to_csv() 方法也可以将数据写入 csv 中。

1.2 读取

import csv

with open('data1.csv', 'r') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        print(row)

结果如下:

['id', 'name', 'age']
['1', 'rose', '18']

Tips:如果有中文需要指定文件编码


pandas 库的 read_csv() 方法

import pandas as pd

df = pd.read_csv('data.csv')
print(df)

运行结果如下:

   id  name  age
0   1  rose   18
1   2  john   19

1.3 避免重复插入表头

#newline的作用是防止每次插入都有空行    
with open("test.csv", "a+", newline='') as csvfile:		# 必须使用 a+,追加方式
        writer = csv.writer(csvfile)
        #以读的方式打开csv 用csv.reader方式判断是否存在标题。
        with open("test.csv", "r", newline="") as f:
            reader = csv.reader(f)
            if not [row for row in reader]:
                writer.writerow(["型号", "分类"])
                writer.writerows([[keyword, miaoshu]])
            else:
                writer.writerows([[keyword, miaoshu]])

示例

爬取一下该网站的所有评论:https://www.bestbuy.ca/en-ca/product/hp-hp-officejet-pro-6968-all-in-one-inkjet-printer-with-fax-6968/10441056/review

import requests
import time
import csv

headers = {
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) "
                      "Version/11.0 Mobile/15A372 Safari/604.1",
        "Referer": "https://www.bestbuy.ca/en-ca/product/hp-hp-officejet-pro-6968-all-in-one-inkjet-printer-with-fax-"
                   "6968/10441056/review"
    }


def get_content(url):
    """爬取数据"""
    res = requests.get(url=url, headers=headers)
    # print(res.status_code)
    return res.json()


def parse_res(res):
    """解析数据"""
    csv_data = {}
    # print(res, type(res))
    data = res["reviews"]
    for i in data:
        csv_data["title"] = i["title"]
        csv_data["comment"] = i["comment"]
        csv_data["publish"] = i["reviewerName"]
        csv_data["publish_time"] = i["submissionTime"]
        print(csv_data)
        save_data(csv_data)


def save_data(csv_data):
    """存储数据"""
    with open('data.csv', 'a+', newline='') as csvfile:
        # 以读的方式打开 csv,判断表格是否有数据
        with open('data.csv', 'r', newline='') as f:
            reader = csv.reader(f)
            fieldnames = ['title', 'comment', 'publish', 'publish_time']
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)		# DictWriter: 字典
            if not [row for row in reader]:
                writer.writeheader()
                writer.writerow(csv_data)
            else:
                writer.writerow(csv_data)

if __name__ == '__main__':
    for i in range(1, 11):
        url = 'https://www.bestbuy.ca/api/v2/json/reviews/10441056?source=all&lang=en-CA&pageSize=10&page=%s' \
              '&sortBy=date&sortDir=desc' % i
        res = get_content(url)
        time.sleep(2)
        parse_res(res)

参考文章:https://blog.csdn.net/qq_41817302/article/details/88680886

1.4 避免读取第一行表头

import csv

l = []

FileObj = open('t.csv')
readerObj = csv.reader(FileObj)

for row in readerObj:
    if readerObj.line_num == 1:		# readerObj.line_num 会返回 csv 文件的行数
        continue
    l.append(row)

print(l)
FileObj.close()
[['1', 'rose', '18'], ['2', 'lila', '19']]

2. JSON 文件存储

2.1 读取 JSON

import json

s = '''
    [{
        "name": "rose",
        "gender": "female",
        "age": "18"
    }]
'''

data = json.loads(s)
print(data)
print(type(data))

运行结果如下:

[{'name': 'rose', 'gender': 'female', 'age': '18'}]
<class 'list'>			# 因为最外层是列表

读取 JSON 文件

with open('data.json', 'r') as f:
    s = f.read()
    data = json.loads(s)
    print(data)

2.2 输出 JSON

import json

data = [{
        "name": "rose",
        "gender": "female",
        "age": "18"
    }]


with open('data.json', 'a') as f:
    f.write(json.dumps(data))

缩进 2 个字符,这样结构更清晰:

with open('data.json', 'a') as f:
    f.write(json.dumps(data, indent=2))

运行结果如下:

[
  {
    "name": "rose",
    "gender": "female",
    "age": "18"
  }
]

如果输出的包含中文,须臾指定参数 ensure_ascii=False,否则默认转换为 Unicode 字符:

with open('data.json', 'a') as f:
    f.write(json.dumps(data, indent=2, ensure_ascii=False))

3. configparser 模块

基本方法

  • 读取配置文件
    • defaults():返回默认 DEFAULT 的值,类型字典
    • read(filename):读取配置文件内容
    • sections():返回所有 section, 类型列表
    • options(section):返回指定 section 的键值对
    • items(section):获取指定 section 所有的键值对
    • get(section, option) 获取指定 section 中 option 的值
    • getint(section, option) 获取指定 section 中option 的值,以 int 类型返回
    • getfloat(section, option) 获取指定 section 中 option 的值,以 float 类型返回
    • getboolean(section, option) 获取指定section 中 option 的值,以 boolean类型返回
  • 写入配置文件
    • add_section(section) 添加指定的新的 section
    • has_section(section) 判断是否存在指定的 section
    • set(section, option, value) 设置指定 section 中 option 的值
    • remove_section(section) 删除指定 section
    • remove_option(section, option) 删除指定 section 中的 option
    • write(fileobject) 将内容写入配置文件

1. 示例:读取、写入 DEFAULT

import configparser

cf = configparser.ConfigParser()
cf.read("user", encoding="utf-8")

cf["DEFAULT"] = {
    "name": 'rose',
    "age": 18,
    "gender": "female"
}

with open("user", 'w')as f:
    cf.write(f)

# 读取
result_dict = cf.defaults()  # 获取默认 DEFAULT,没有就返回空的字典 OrderedDict()
print(result_dict)

运行结果:

[DEFAULT]
name = rose
age = 18
gender = female

OrderedDict([('name', 'rose'), ('age', '18'), ('gender', 'female')])

2. 示例二:逐行读取(读取单个 option)

def read_ini(section, option):
    """读取 ini 文件"""
    try:
        config = configparser.RawConfigParser()
        config.read('ui', encoding='gbk')
        content = config.get(section, option)
        return content
    except Exception as ex:
        print(ex)

3. 读取所有key-value

1、user

[audio]
name = rose
age = 18
gender = female

[video]
width = 1980
height = 1080

2、读取所有 key-value

def read():
    """读取配置文件"""
    results = {}
    cf = configparser.ConfigParser()
    cf.read('user', encoding='gbk')

    # 全部读取并写入到字典中
    for section in cf.sections():
        temp = {section: {}}
        options = cf.options(section)
        for i in options:
            temp[section].update({i: cf.get(section, i)})
        results.update(temp)

    print('results===>', results)

    return results

运行结果:{'audio': {'name': 'rose', 'age': '18', 'gender': 'female'}, 'video': {'width': '1980', 'height': '1080'}}

4. 以字典形式存取

cf = configparser.ConfigParser()
cf['encode'] = {
    'bitrate_type': 0,
    'bitrate': 25,
    'goplen': 40,
}

cf['system'] = {
    'version': '1.0.2',
    'hmode': 1686
}

with open("ui", "w+") as f:
    cf.write(f)

5. 写入

def user_write(self, results: dict):
    """将用户信息写入配置文件
        {"mac": {"mac": "1111111111"}}
        """
    cf = configparser.ConfigParser()
    results_dic = {k1: v1 for k1, v1 in results.items() if isinstance(v1, dict)}

    for k2, v2 in results_dic.items():
        if not .cf.has_section(k2):
            cf.add_section(k2)
            for k3, v3 in v2.items():
                if not cf.has_option(k2, k3):
                    cf.set(k2, k3, v3)

                    with open('user', 'w+') as f:
            cf.write(f)

参考

  • configparser 模块的基本方法:https://www.cnblogs.com/gexbooks/p/12103709.html
  • python:利用configparser模块读写配置文件:https://www.cnblogs.com/imyalost/p/8857896.html

4. shutil 模块

复制、改名和删除文件、文件夹

4.1 复制文件和文件夹

  • copy(source, dest):拷贝文件,返回被拷贝文件后的路径(字符串)
  • copytree(source, dest):拷贝文件夹/目录,返回被拷贝文件夹后的路径(字符串)

a、b 两个文件夹在同级目录,a 中有一个文件 s1.py,b 中为空:

>>> import shutil

>>> shutil.copy('a/s1.py', 'b')     # 使用默认名称
'b\\s1.py'

>>> shutil.copy('a/s1.py', 'b/s2.py')   # 重新命名
'b/s2.py'

>>> shutil.copytree('a', 'b\\a')
'b\\a'

4.2 文件和文件夹的移动和重命名

  • 移动文件,原有文件将会被删除,返回新位置的绝对路径
  • 若目标路径是一个文件夹,那么文件将被移动到文件夹中
  • 若目标路径不存在,那么将重命名为那个路径
  • 若目标路径中存在同名文件,则会被覆盖
>>> shutil.move('a\\s1.py', 'b')
'b\\s1.py'

# c 文件夹不存在,s1.py 重命名为 c
>>> shutil.move('b\\s1.py', 'c')
'c'

# 重命名
>>> shutil.move('b\\s1.py', 'a\\s2.py')
'a\\s2.py'

4.3 删除文件和文件夹

  • os.unlink(path):删除 path 处的文件
  • os.rmdir(path):删除 path 处的文件夹,该文件夹必须为空
  • shutil.rmtree(path):删除 path 处所有文件及文件夹

4.4 安全删除文件

send2transh 模块不会永久删除文件,而是将其移动到回收站,以便恢复,而 os.unlink()、shutil.rmtree() 是永久删除:

pip install send2trash

send2trash.send2trash('a.py')

4.5 遍历目录树

os.walk(path) 返回:

  • 当前文件夹
  • 当前文件夹中的子文件夹字符串列表
  • 当前文件夹中的文件字符串列表

目录结构:

a
    - b
    - s1.py
s1.py
b

示例:

# -*- coding: utf-8 -*-

import os

for folderName, subfolders, filenames in os.walk('a'):
    print('当前文件夹:', folderName)

    for subfolder in subfolders:
        print('子文件夹:', subfolder)

    for filename in filenames:
        print('文件:', filename)

# >>> for folderName, subfolders, filename in os.walk('a'):
# ...     print('当前文件夹:{},当前文件夹中子文件的字符串列表:{},当前文件夹中文件字符串列表:{}'.format(folderName, subfolders, filename))
# ...
# 当前文件夹:a,当前文件夹中子文件的字符串列表:['b'],当前文件夹中文件字符串列表:['s1.py']
# 当前文件夹:a\b,当前文件夹中子文件的字符串列表:[],当前文件夹中文件字符串列表:[]

运行结果:

当前文件夹: a
子文件夹: b
文件: s1.py
当前文件夹: a\b
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风老魔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值