era5数据内容说明_关于爬取网站数据保存为docx出现的一些问题

最近同事在爬取某网站数据,想将爬取的数据保存为docx。在爬取数据过程中一切很顺利,但是在保存数据时却提示以下错误。

  File "srclxmletree.pyx", line 1024, in lxml.etree._Element.text.__set__  File "srclxmlapihelpers.pxi", line 747, in lxml.etree._setNodeText  File "srclxmlapihelpers.pxi", line 735, in lxml.etree._createTextNode  File "srclxmlapihelpers.pxi", line 1540, in lxml.etree._utf8ValueError: All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters

数据保存使用的是python-docx模块。大致意思是字符不兼容,所有字符串必须与XML兼容。

那么接下来面向百度或谷歌编程,根据百度搜索结果。大致意思是python-docx与中文字符不兼容,需要将字符转为Unicode。让我们先来看看字符的数据内容,和字符数据格式。

def save(doc_title, doc_content_list):    document = Document()    # 测试标题    heading = document.add_heading(doc_title, 0)    # 居中显示    heading.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER    #打印字符集    print(chardet.detect(doc_content_list.encode()))    #打印数据内容    print(doc_content_list)    # 测试内容,这里转为Unicode    document.add_paragraph(doc_content_list)    # 字符分割,用于保存文件名    t_title = doc_title.split()[0]    # 运行    document.save('下载-%s.docx' % t_title)

运行结果如下所示

9bfd19bc096f2cddde390eb98eccbdab.png

字符集和数据内容

数据内容好像没问题,字符集为utf-8。

难道是python-docx与中文字符真的不兼容?着手写了一个测试如下

from docx.enum.text import WD_PARAGRAPH_ALIGNMENT  # 用来居中显示标题from docx import Documentdocument = Document()#测试标题,注意这里忘了转为Unicodeheading = document.add_heading("测试标题", 0)heading.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 居中显示#测试内容,这里转为Unicodedocument.add_paragraph(u'测试内容')document.save('测试文档.docx')

最后运行一切正常,保存成功。

deef6a1890d583cd29fa4df4e7daf6b6.png

测试结果

在写测试标题的时候忘了将字符转为Unicode,但是也能够正常保存,说明python-docx是能够支持utf-8字符集。而测试内容转为了Unicode,但是在文档中也能正常显示,说明python-docx在保存Unicode的时候会默认转为utf-8。

按理论上了来说,python-docx在保存数据的时候是没有问题的,那为什么会报错呢?那我们将网站上爬取的数据转为Unicode试试。大致代码如下

def save(doc_title, doc_content_list):    document = Document()    # 测试标题    heading = document.add_heading(doc_title, 0)    # 居中显示    heading.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER      # 测试内容,这里转为Unicode    document.add_paragraph(json.dumps(doc_content_list))    # 字符分割,用于保存文件名    t_title = doc_title.split()[0]    # 在当前脚本路径存储docx文件    document.save('下载-%s.docx' % t_title)

使用json.dumps将字符串转为Unicode,加上这一步操作后,运行过程中没有任何异常,但是运行结果却不是我们所想要的。大致运行结果如下图所示

c755e79cb7558195dca44ec038c321d4.png

运行结果

当场我就纳闷了,怎么标题保存没问题,但是内容保存却是Unicode,按理论来说内容应该会直接转为utf-8啊。

懵逼之后,我整理了下思路:

  1. 数据可以打印,说明数据获取没问题
  2. 数据格式为utf-8
  3. python-docx可以直接保存utf-8数据集,也可以保存Unicode格式
  4. python-docx将数据保存为Unicode不报错,但是显示有问题
  5. python-docx将数据直接以utf-8保存,报错

整理思路,说明我们的数据可能有问题。我们回过头来看下错误提示

All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters

所有字符串必须与XML兼容:Unicode或ASCII,不能是空字节或控制字符。

接下来我们尝试将得到的数据清理下,将所有非utf-8的字符去掉。大致代码如下

from docx.enum.text import WD_PARAGRAPH_ALIGNMENTfrom docx import Documentimport re# 清理所有非utf-8的字符def cleantxt(raw):    # utf-8字符集范围u4e00-u9fa5     fil = re.compile(u'[^0-9a-zA-Z一-龥.,,。?“”《》_()!;:]+', re.UNICODE)    return fil.sub(' ', raw)def save(doc_title, doc_content_list):    document = Document()    # 测试标题    heading = document.add_heading(doc_title, 0)    # 居中显示    heading.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER    # 测试内容,清理异常数据    document.add_paragraph(cleantxt(doc_content_list))    # 字符分割,用于保存文件名    t_title = doc_title.split()[0]    # 在当前脚本路径存储docx文件    document.save('下载-%s.docx' % t_title)

运行一切正常,接下来到了激动人心的时刻了。

53bc88dcdddf2e521a24f87914195d30.png

运行结果

终于得到了想要的结果,在此记录遇到问题的场景和解决问题的思路和方法和大家共享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值