【Python学习 】如何将UTF-8编码转换成UTF-8 BOM编码?

本文介绍了如何使用Python脚本来快速将UTF-8编码的文件转换为UTF-8 BOM编码,以便在TextAnalysisTool工具中正确解析中文日志,同时提供了将转换操作整合到Windows右键菜单的教程。
摘要由CSDN通过智能技术生成

一、需求描述

在我之前的博客:
【我的Android进阶之旅】使用TextAnalysisTool来快速提高你分析文本日志的效率
中有介绍下面一个关于中文无法显示的问题,如下所示:


有时候,中文无法正常显示,如下所示都是乱码

在这里插入图片描述
这个时候,我们需要借助下 NotePad++ 工具,对整个日志文件进行转码,如下所示

我们发现,此文件用NotePad++ 打开,可以直接显示中文,
编码格式为 UTF-8编码

在这里插入图片描述

我们使用快捷键 Ctrl+A 全选日志内容,选择【编码】–>【使用 UTF-8 BOM编码】,将日志内容切换编码,然后保存。

在这里插入图片描述

现在我们切换了编码为【UTF-8 BOM】之后,重新用TextAnalysisTool工具打开这份日志就可以正常显示中文了

在这里插入图片描述


上面的方法,我们通过使用NotePad++ 工具,来对整个日志文件进行转码。然后再进行查看,这样的步骤有点繁琐。有时候需要分析多份日志的时候就会显得很恶心。

所以在想,有没有其他的方式将utf-8编码转成utf-8 BOM编码呢?

二、实现需求:将UTF-8编码转成UTF-8 BOM编码

我们可以使用python来实现这个需求。

2.1 了解下UTF-8 and UTF-8 BOM(Byte Order Mark)的区别

大家可以通过以下几个链接了解一下UTF-8 and UTF-8 BOM(Byte Order Mark)的区别。

结论:

UTF-8 不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM。
所以不含 BOM 的 UTF-8 才是标准形式,在 UTF-8 文件中放置 BOM 主要是微软的习惯(顺便提一下:把带有 BOM 的小端序 UTF-16 称作「Unicode」而又不详细说明,这也是微软的习惯)。

什么是BOM

BOM(byte-order mark),即字节顺序标记,它是插入到以UTF-8、UTF16或UTF-32编码Unicode文件开头的特殊标记,用来识别Unicode文件的编码类型。

对于UTF-8来说,BOM并不是必须的,因为BOM用来标记多字节编码文件的编码类型和字节顺序(big-endian或little-endian)。

在绝大多数编辑器中都看不到BOM字符,因为它们能理解Unicode,去掉了读取器看不到的题头信息。若要查看某个Unicode文件是否以BOM开头,可以使用十六进制编辑器。下表列出了不同编码所对应的BOM。

BOM Encoding
EF BB BF UTF-8
FE FF UTF-16 (big-endian)
FF FE UTF-16 (little-endian)
00 00 FE FF UTF-32 (big-endian)
FF FE 00 00 UTF-32 (little-endian)

UTF-8以字节为编码单元因此不需要 BOM 来表明字节顺序,但可以用 BOM 来表明编码方式。字符 “Zero Width No-Break Space” 的 UTF-8 编码是 EF BB BF。所以如果接收者收到以 EF BB BF 开头的字节流,就知道这是 UTF-8编码了。

在这里插入图片描述

因此UTF-8编码的字符串开头处的三个bytes 0xef,0xbb,0xbf就称为UTF-8 BOM头。

BOM的来历

为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE(U+FEFF)字符开头。这作为一个“特征符”或“字节顺序标记(byte-order mark,BOM)”来识别文件中使用的编码和字节顺序。

Linux/UNIX 并没有使用 BOM,因为它会破坏现有的 ASCII 文件的语法约定。

带BOM和不带BOM的区别

「UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即文件开头有没有 U+FEFF,也就是说有没有这个标记。

在这里插入图片描述
但内容都一样 ,为什么相差了3个字节呢 ? 如下图 。

在这里插入图片描述
多出来的 ef bb bf 就是上面相差三个字节的原因 。

BOM——Byte Order Mark,就是字节序标记

bom是为utf-16和utf-32准备的,用于标记字节顺序。微软在utf-8中使用bom是因为这样可以把UTF-8和ASCII等编码区分开来,但这样的文件在windows之外的操作系统里会带来问题。

带还是不带?

如果你的编程平台需要跨平台编译,比如,会在linux平台上编译,而不是只在windows上运行,建议不带BOM,unicode标准就是不带,带BOM毕竟那是微软的那一套,带了会出现很大的问题。反之,如果你的程序只在windows平台上编译出windows程序,这个可有可无。
注意:这里所说的带还是不带,指的是:源码字符集(the source character set)-源码文件是使用何种编码保存的;

现在linux平台下的GCC 4.6及以上的版本已经可以支持带BOM的源码了!!!!!
所以之前出现的问题也可以不用冲突,带或者不带,以后就不会成为一个问题。

2.2 实现需求

参考链接: 【Adding BOM (unicode signature) while saving file in python】

import codecs
# https://stackoverflow.com/questions/5202648/adding-bom-unicode-signature-while-saving-file-in-python


""" 给指定文件,添加BOM标记
    参数:
        file: 文件
        bom: BOM标记
"""
def add_bom(file, bom: bytes):
    with open(file, 'r+b') as f:
        org_contents = f.read()
        f.seek(0)
        f.write(bom + org_contents)

# 定义一个测试文件,名为test.log
file = 'test.log'

# 打开 测试文件,使用utf-8编码写入一段中英文混杂的内容
with open(file, 'w', encoding='utf-8') as f:  # without BOM
    f.write('欧阳鹏 博客地址:https://blog.csdn.net/ouyang_peng')

# 加入BOM标记
#add_bom(file, codecs.BOM_UTF8)

# 打开测试文件,打印文件内容
with open(file, 'rb') as f:
    print(f.read())

在这里插入图片描述

总共有4个区域:

  • 区域1
    定义 add_bom方法,给指定文件,添加BOM标记
  • 区域2
    定义一个测试文件,名为test.log,打开 测试文件,使用utf-8编码写入一段中英文混杂的内容
  • 区域3
    给测试文件,加入BOM标记
  • 区域4
    打印测试文件的内容

2.2.1 测试写入utf-8内容并读取打印

import codecs
# https://stackoverflow.com/questions/5202648/adding-bom-unicode-signature-while-saving-file-in-python


""" 给指定文件,添加BOM标记
    参数:
        file: 文件
        bom: BOM标记
"""
def add_bom(file, bom: bytes):
    with open(file, 'r+b') as f:
        org_contents = f.read()
        f.seek(0)
        f.write(bom + org_contents)

# 定义一个测试文件,名为test.log
file = 'test.log'

# 打开 测试文件,使用utf-8编码写入一段中英文混杂的内容
with open(file, 'w', encoding='utf-8') as f:  # without BOM
    f.write('欧阳鹏 博客地址:https://blog.csdn.net/ouyang_peng')

# 加入BOM标记
#add_bom(file, codecs.BOM_UTF8)

# 打开测试文件,打印文件内容
with open(file, 'rb') as f:
    print(f.read())

运行程序,如下所示:

[Running] python -u "c:\Users\000\Desktop\add_utf8_bom.py"
b'\xe6\xac\xa7\xe9\x98\xb3\xe9\xb9\x8f \xe5\x8d\x9a\xe5\xae\xa2\xe5\x9c\xb0\xe5\x9d\x80\xef\xbc\x9ahttps://blog.csdn.net/ouyang_peng'

[Done] exited with code=0 in 1.038 seconds

在这里插入图片描述

使用 TextAnalysisTool 工具打开,乱码
在这里插入图片描述

2.2.2 测试写入utf-8内容,并给文件加入BOM标记,然后读取打印

import codecs
# https://stackoverflow.com/questions/5202648/adding-bom-unicode-signature-while-saving-file-in-python


""" 给指定文件,添加BOM标记
    参数:
        file: 文件
        bom: BOM标记
"""
def add_bom(file, bom: bytes):
    with open(file, 'r+b') as f:
        org_contents = f.read()
        f.seek(0)
        f.write(bom + org_contents)

# 定义一个测试文件,名为test.log
file = 'test.log'

# 打开 测试文件,使用utf-8编码写入一段中英文混杂的内容
with open(file, 'w', encoding='utf-8') as f:  # without BOM
    f.write('欧阳鹏 博客地址:https://blog.csdn.net/ouyang_peng')

# 加入BOM标记
add_bom(file, codecs.BOM_UTF8)

# 打开测试文件,打印文件内容
with open(file, 'rb') as f:
    print(f.read())

输出内容为:

[Running] python -u "c:\Users\000\Desktop\add_utf8_bom.py"
b'\xef\xbb\xbf\xe6\xac\xa7\xe9\x98\xb3\xe9\xb9\x8f \xe5\x8d\x9a\xe5\xae\xa2\xe5\x9c\xb0\xe5\x9d\x80\xef\xbc\x9ahttps://blog.csdn.net/ouyang_peng'

[Done] exited with code=0 in 1.043 seconds

在这里插入图片描述
使用 TextAnalysisTool 工具打开,不会乱码了!
在这里插入图片描述

2.2.2 对比输出内容

[Running] python -u "c:\Users\000\Desktop\add_utf8_bom.py"
b'\xe6\xac\xa7\xe9\x98\xb3\xe9\xb9\x8f \xe5\x8d\x9a\xe5\xae\xa2\xe5\x9c\xb0\xe5\x9d\x80\xef\xbc\x9ahttps://blog.csdn.net/ouyang_peng'

[Done] exited with code=0 in 1.038 seconds

[Running] python -u "c:\Users\000\Desktop\add_utf8_bom.py"
b'\xef\xbb\xbf\xe6\xac\xa7\xe9\x98\xb3\xe9\xb9\x8f \xe5\x8d\x9a\xe5\xae\xa2\xe5\x9c\xb0\xe5\x9d\x80\xef\xbc\x9ahttps://blog.csdn.net/ouyang_peng'

[Done] exited with code=0 in 1.043 seconds

在这里插入图片描述

对比 UTF-8 和 UTF-8 BOM的内容,可以发现,多了\xef\xbb\xbf三个字节,因此UTF-8编码的字符串开头处的三个bytes 0xef,0xbb,0xbf就称为UTF-8 BOM头。

三、扩展

3.1 扩展为可实际使用的脚本

上面的demo我们测试完毕之后,我们扩展一下,使之扩展为可实际使用的脚本。

add_utf8_bom.py 的代码如下,

import sys
import os
import glob
import codecs

""" 给指定文件,添加BOM标记
    参数:
        file: 文件
        bom: BOM标记
"""
def add_bom(file, bom: bytes):
    print("now,add_bom for file :[%s] ,with bom:[%s]" %(file,bom))
    with open(file, 'r+b') as f:
        org_contents = f.read()
        f.seek(0)
        f.write(bom + org_contents)

""" 根据给定的不同参数,给指定文件,添加BOM标记
    参数:
      args  传入进来的参数。
      
      如果参数只有一个,则区分是目录还是文件,
            如果是文件夹,则遍历文件夹中的.log日志文件,然后给每个.log日志文件添加BOM标记
            如果是文件则直接添加BOM标记。
      
      如果不传参数,则直接遍历当前目前下的所有.log日志文件  
"""
def main(args):
    if 1 == len(args):
        if os.path.isdir(args[0]):
            filelist = glob.glob(args[0] + "/*.log")
            for filepath in filelist:
                add_bom(filepath, codecs.BOM_UTF8)
        else:
            add_bom(args[0], codecs.BOM_UTF8)
    else:
        filelist = glob.glob("*.log")
        for filepath in filelist:
            add_bom(filepath, codecs.BOM_UTF8)

if __name__ == "__main__":
    main(sys.argv[1:])

我们来做一下测试,我们准备一个目录 C:\Users\000\Desktop\test_bom,放好写好的脚本,以及4个utf-8格式的文件,如下所示:

在这里插入图片描述
文件打开是乱码的

在这里插入图片描述

3.1.1 传入一个指定文件路径

如下所示:指定传入一个指定的文件名。文件名可以传入相对路径或者绝对路径。

  • 相对路径
PS C:\Users\000> cd "c:\Users\000\Desktop\test_bom"
PS C:\Users\000\Desktop\test_bom> python -u "c:\Users\000\Desktop\test_bom\add_utf8_bom.py" "test_utf-8.log"
now,add_bom for file :[test_utf-8.log] ,with bom:[b'\xef\xbb\xbf']
PS C:\Users\000\Desktop\test_bom> 

在这里插入图片描述

  • 绝对路径
PS C:\Users\000\Desktop\test_bom> python -u "c:\Users\000\Desktop\test_bom\add_utf8_bom.py" "C:\Users\000\Desktop\test_bom\test_utf-8.log" 
now,add_bom for file :[C:\Users\000\Desktop\test_bom\test_utf-8.log] ,with bom:[b'\xef\xbb\xbf']
PS C:\Users\000\Desktop\test_bom>

在这里插入图片描述
两种方式都可以识别,然后可以看到日志打印,添加了BOM标记头。

我们可以看到C:\Users\000\Desktop\test_bom\test_utf-8.log的时间和其他的文件不同,以被修改。
在这里插入图片描述
打开文件内容查看,不乱码!
在这里插入图片描述

3.1.2 传入一个指定文件夹路径

传入一个指定文件夹路径,如下所示,传入文件夹路径为:C:\Users\000\Desktop\test_bom\

PS C:\Users\000\Desktop\test_bom> python -u "c:\Users\000\Desktop\test_bom\add_utf8_bom.py" "C:\Users\000\Desktop\test_bom\"
now,add_bom for file :[C:\Users\000\Desktop\test_bom\test_utf-8  (1).log] ,with bom:[b'\xef\xbb\xbf']
now,add_bom for file :[C:\Users\000\Desktop\test_bom\test_utf-8  (2).log] ,with bom:[b'\xef\xbb\xbf']
now,add_bom for file :[C:\Users\000\Desktop\test_bom\test_utf-8  (3).log] ,with bom:[b'\xef\xbb\xbf']
now,add_bom for file :[C:\Users\000\Desktop\test_bom\test_utf-8.log] ,with bom:[b'\xef\xbb\xbf']
PS C:\Users\000\Desktop\test_bom>

在这里插入图片描述

我们可以看到该文件夹下所有的log日志文件都被修改。

打开该文件夹下所有的log日志文件,查看下内容不乱码!
在这里插入图片描述

3.1.3 不传入指定路径

不传入指定路径,则会遍历当前路径下所有的.log日志文件。

PS C:\Users\000\Desktop\test_bom> python -u "c:\Users\000\Desktop\test_bom\add_utf8_bom.py"
now,add_bom for file :[test_utf-8  (1).log] ,with bom:[b'\xef\xbb\xbf']
now,add_bom for file :[test_utf-8  (2).log] ,with bom:[b'\xef\xbb\xbf']
now,add_bom for file :[test_utf-8  (3).log] ,with bom:[b'\xef\xbb\xbf']
now,add_bom for file :[test_utf-8.log] ,with bom:[b'\xef\xbb\xbf']
PS C:\Users\000\Desktop\test_bom>

在这里插入图片描述
和传入指定文件夹路径的效果类似。

3.2 将Python脚本加入Windows右键菜单

写一个工具直接鼠标右键一键可以转换UTF-8编码转换成UTF-8 BOM编码,方便我在windows电脑上使用TextAnalysisTool工具来分析日志。

具体可以参考下面这个操作

我们来看实际效果。

3.2.1 先写一个批处理文件

现在我们将这个命令封装成一个bat文件,这样我们以后就可以直接运行bat文件即可,不需要每次都敲命令了。

比如我们封装为 add_utf_bom.bat 文件,放在C:\Windows目录下,内容如下

在这里插入图片描述

add_utf_bom.bat 文件源代码如下:

C:\Python39\python.exe C:\Windows\add_utf8_bom.py %*

  • 第一个参数 C:\Python39\python.exe 表示要运行的python程序的路径,上面的python.exe文件在c:\Python39目录下,如下所示
    在这里插入图片描述

如果你的python文件不是这个目录,改为你自己的python安装目录。

  • 第二个参数 C:\Windows\add_utf8_bom.py 表示添加BOM标记的python脚本路径

3.2.2 先写一个注册表文件

在这里插入图片描述

add_utf_bom.reg文件的内容为:

Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\shell\add_utf_bom\command]
@="add_utf_bom.bat \"%1\""

然后双击该注册表,即可导入注册表。

在这里插入图片描述
点击 【是(Y)】,即可导入成功!

在这里插入图片描述
导入注册表成功之后,查询下注册表内容,如下所示:

在这里插入图片描述

3.2.3 测试鼠标右键add_utf_bom菜单

在这里插入图片描述
一闪而过,执行成功
在这里插入图片描述

在这里插入图片描述

OK,整个需求完整实现,可以对指定的utf-8编码的文件,先使用鼠标右键菜单【add_utf_bom】实现添加BOM头的功能,然后再使用TextAnalysisTool工具来查看不乱码的日志文件!

四、再次扩展功能:添加完BOM头之后,直接用TextAnalysisTool工具打开此文件

4.1 待优化的现状

上面的步骤做完之后,我们可以很方便的给文件进行转码,给UTF-8格式的文件加上BOM头,使之可以使用TextAnalysisTool工具打开此文件后不乱码。
但是这样得进行两步骤

  1. 鼠标右键: 选择我们弄好的【add_utf_bom】菜单项,进行编码转换

在这里插入图片描述
2. 重新打开此文件
在这里插入图片描述
略显麻烦,因此我想把两个步骤合并为一个,当点击鼠标右键: 选择我们弄好的【add_utf_bom】菜单项,进行编码转换之后,直接使用TextAnalysisTool工具打开此文件。

4.2 实现功能

因此我们修改下python脚本即可。

import sys
import os
import glob
import codecs

""" 给指定文件,添加BOM标记
    参数:
        file: 文件
        bom: BOM标记
"""
def add_bom(file, bom: bytes):
    print("now,add_bom for file :[%s] ,with bom:[%s]" %(file,bom))
    with open(file, 'r+b') as f:
        org_contents = f.read()
        f.seek(0)
        f.write(bom + org_contents)

""" 根据给定的不同参数,给指定文件,添加BOM标记
    参数:
      args  传入进来的参数。
      
      如果参数只有一个,则区分是目录还是文件,
            如果是文件夹,则遍历文件夹中的.log日志文件,然后给每个.log日志文件添加BOM标记
            如果是文件则直接添加BOM标记。
      
      如果不传参数,则直接遍历当前目前下的所有.log日志文件  
"""
def main(args):
    if 1 == len(args):
        if os.path.isdir(args[0]):
            filelist = glob.glob(args[0] + "/*.log")
            for filepath in filelist:
                add_bom(filepath, codecs.BOM_UTF8)
        else:
            add_bom(args[0], codecs.BOM_UTF8)
            # 如果是单独打开某个文件,肯定是鼠标右键进来的,或者直接指定要打开这个文件的
            # 那么加上BOM标记之后,直接使用TextAnalysisTool工具直接打开
            # TextAnalysisTool 工具安装的路径为: D:\TextAnalysisTool.NET\TextAnalysisTool.NET.exe
            # 所以直接打开此文件
            # TextAnalysisTool 安装目录为: D:\TextAnalysisTool.NET
            # TextAnalysisTool 程序名为: TextAnalysisTool.NET.exe
            # 要打开的文件为: args[0] 传进来的参数
            os.system('start "" /d "D:\TextAnalysisTool.NET" /wait "TextAnalysisTool.NET.exe" %s' %args[0])
    else:
        filelist = glob.glob("*.log")
        for filepath in filelist:
            add_bom(filepath, codecs.BOM_UTF8)

if __name__ == "__main__":
    main(sys.argv[1:])

添加了标红的一段代码
在这里插入图片描述
TextAnalysisTool 工具安装的路径为: D:\TextAnalysisTool.NET\TextAnalysisTool.NET.exe
在这里插入图片描述
添加的部分代码如下所示:

# 如果是单独打开某个文件,肯定是鼠标右键进来的,或者直接指定要打开这个文件的
            # 那么加上BOM标记之后,直接使用TextAnalysisTool工具直接打开
            # TextAnalysisTool 工具安装的路径为: D:\TextAnalysisTool.NET\TextAnalysisTool.NET.exe
            # 所以直接打开此文件
            # TextAnalysisTool 安装目录为: D:\TextAnalysisTool.NET
            # TextAnalysisTool 程序名为: TextAnalysisTool.NET.exe
            # 要打开的文件为: args[0] 传进来的参数
            os.system('start "" /d "D:\TextAnalysisTool.NET" /wait "TextAnalysisTool.NET.exe" %s' %args[0])

4.3 测试一键转码并打开功能

在这里插入图片描述
转码中
在这里插入图片描述
自动打开转码后的文件
在这里插入图片描述
恩,到此为止,这个工具用起来才得心应手!

五、参考链接

### 回答1: 可以使用Python中的pandas库来实现将csv文件编码utf-8格式的操作。具体代码如下: ```python import pandas as pd # 读取csv文件 df = pd.read_csv("your_file.csv") # 将编码格式转换为utf-8 df.to_csv("your_file_utf8.csv", encoding='utf-8', index=False) ``` 在上述代码中,我们首先使用pandas库的read_csv函数读取csv文件,并将其存储为名为df的数据框。接着,我们使用to_csv函数将数据框转换为以utf-8编码格式存储的csv文件,并将其保存在名为your_file_utf8.csv的文件中。注意,在to_csv函数中,我们需要指定参数encoding为'utf-8',以确保输出文件的编码格式为utf-8。同时,我们也将参数index设置为False,以避免在输出文件中保存索引列。 ### 回答2: 要将csv文件编码utf-8格式,可以使用Python的csv模块和codecs模块来实现。 首先,需要导入csv模块和codecs模块。然后,使用codecs模块的open函数打开csv文件,并指定使用utf-8编码。 然后,使用csv模块的reader函数读取csv文件的内容。将读取的内容按行存储到一个列表中。 接下来,在内存中创建一个新的csv文件,并使用csv模块的writer函数来写入内容。 然后,遍历之前存储的行列表,并使用writerow函数将每一行写入新的csv文件中。 最后,关闭原始csv文件和新的csv文件。 以下是示例代码: ```python import csv import codecs # 打开原始csv文件 with codecs.open('原始文件.csv', 'r', encoding='utf-8') as f: reader = csv.reader(f) rows = [row for row in reader] # 创建新的csv文件 with codecs.open('新文件.csv', 'w', encoding='utf-8') as f: writer = csv.writer(f) for row in rows: writer.writerow(row) # 关闭文件 f.close() ``` 这样,就可以将csv文件转换为utf-8格式保存为新的csv文件。注意确保原始文件的编码与指定的编码一致,以避免乱码。 ### 回答3: 要将CSV文件编码utf-8格式,可以使用Python编程语言的csv库和codecs库。首先,导入所需的库。 ```python import csv import codecs ``` 然后,打开原始的CSV文件和新的UTF-8编码的CSV文件。 ```python with open('input.csv', 'r', encoding='utf-8-sig') as file: # 打开原始的CSV文件,使用utf-8-sig解码文本中的BOM字符 reader = csv.reader(file) rows = [row for row in reader] with codecs.open('output.csv', 'w', 'utf-8-sig') as file: # 打开新的UTF-8编码的CSV文件,使用utf-8-sig编码文本中的BOM字符 writer = csv.writer(file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) writer.writerows(rows) ``` 在上述代码中,使用csv.reader()函数读取原始CSV文件,并使用列表推导式将其保存为一个名为rows的列表。然后,使用codecs.open()函数打开新的UTF-8编码的CSV文件,将rows中的内容写入该文件中。 请注意,'input.csv'是原始的CSV文件的路径,而'output.csv'是新的UTF-8编码的CSV文件的路径。要成功运行该代码,请确保将实际的文件路径用于这些参数。 这样,CSV文件就会被编码utf-8格式并保存在新的文件中(output.csv)。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

字节卷动

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

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

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

打赏作者

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

抵扣说明:

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

余额充值