Python Camelot PDF-在Windows上使用Stream风格时出现UnicodeEncodeError

问题描述

Windows 10上的python3.7。Camelot0.8.2

我正在使用以下代码将pdf文件转换为HTML:

import camelot
import os
 
def CustomScript(args):
    path_to_pdf = "C:\PDFfolder\abc.pdf"        
    folder_to_pdf = os.path.dirname(path_to_pdf)
    tables = camelot.read_pdf(os.path.normpath(path_to_pdf),flavor='stream',pages='1-end')
    tables.export(os.path.normpath(os.path.join(folder_to_pdf,"temp","foo.html")),f='html')
    return CustomScriptReturn.Empty();

我在tables.export行收到以下错误

“ UnicodeEncodeError-'charmap'编解码器无法编码字符'\ u2010' 在y位置:字符映射为undefined。

代码在Mac上运行没有问题。该错误似乎与Windows有关,这是我需要在其上运行的环境。

我现在已经花了整整两天的时间研究此错误恶心-我从与此相关的几篇文章中尝试了Stack Overflow此处提供的许多解决方案。错误仍然存​​在。添加所有解决方案中建议的代码行的问题在于,它们都是要添加到原始Python方法中的参数。这些参数不适用于Camelot的export方法

编辑1::更新了帖子,以指定引发错误的行。

编辑2:使用的PDF文件http://tsbde.texas.gov/78i8ljhbj/Fiscal-Year-2014-Disciplinary-Actions.pdf

编辑3:这是从Windows控制台进行的完整追溯:

> Traceback (most recent call last):   File "main.py",line 18,in
> <module>
>     tables.export(os.path.normpath(os.path.join(folder_to_pdf,f='html')   File
> "C:\Users\stpete\AppData\Local\Programs\Python\python37\lib\site-packages\camelot\core.py",> line 737,in export
>     self._write_file(f=f,**kwargs)   File "C:\Users\stpete\AppData\Local\Programs\Python\python37\lib\site-packages\camelot\core.py",> line 699,in _write_file
>     to_format(filepath)   File "C:\Users\stpete\AppData\Local\Programs\Python\python37\lib\site-packages\camelot\core.py",> line 636,in to_html
>     f.write(html_string)   File "C:\Users\stpete\AppData\Local\Programs\Python\python37\lib\encodings\cp1252.py",> line 19,in encode
>     return codecs.charmap_encode(input,self.errors,encoding_table)[0] UnicodeEncodeError: 'charmap' codec can't encode character '\u2010' in
> position 5737: character maps to <undefined>

解决方法

您面临的问题与方法camelot.core.Table.to_html有关:

def to_html(self,path,**kwargs):
"""Writes Table to an HTML file.
For kwargs,check :meth:`pandas.DataFrame.to_html`.
Parameters
----------
path : str
    Output filepath.
"""
html_string = self.df.to_html(**kwargs)
with open(path,"w") as f:
    f.write(html_string)

这里,要写入的文件应使用UTF-8编码打开,而不是打开。

这是我的解决方案,它使用猴子补丁代替了原始的驼鹿方法:

import camelot
import os

# here I define the corrected method
def to_html(self,**kwargs):
    """Writes Table to an HTML file.
    For kwargs,check :meth:`pandas.DataFrame.to_html`.
    Parameters
    ----------
    path : str
        Output filepath.
    """
    html_string = self.df.to_html(**kwargs)
    with open(path,"w",encoding="utf-8") as f:
        f.write(html_string)

# monkey patch: I replace the original method with the corrected one
camelot.core.Table.to_html=to_html

def CustomScript(args):
    path_to_pdf = "C:\PDFfolder\abc.pdf"        
    folder_to_pdf = os.path.dirname(path_to_pdf)
    tables = camelot.read_pdf(os.path.normpath(path_to_pdf),flavor='stream',pages='1-end')
    tables.export(os.path.normpath(os.path.join(folder_to_pdf,"temp","foo.html")),f='html')
    return CustomScriptReturn.Empty();

我测试了此解决方案,它适用于Python 3.7,Windows 10,Camelot 0.8.2。

,

您将得到UnicodeEncodeError,在这种情况下,这意味着要写入文件的输出包含一个字符,该字符无法使用您平台的默认编码cp1252进行编码。

writing to an html file时,camelot似乎无法处理编码设置。

一种解决方法是在运行程序时将PYTHONIOENCODING环境变量设置为“ UTF-8”:

C:\> set PYTHONIOENCODING=UTF-8 && python myprog.py 

强制使用UTF-8编码输出文件。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...