python 3.2 UnicodeEncodeError:'charmap'编解码器不能在位置9629编码字符'\ u2013':字符映射到<undefined>

我试图做一个脚本,从sqlite3数据库中获取数据,但我遇到了一个问题。

数据库中的字段是文本types,并包含html格式的文本。 看下面的文字

<html> <head> <title>Yahoo!</title> </head> <body> <style type="text/css"> html {} .yshortcuts {border-bottom:none !important;} .ReadMsgBody {width:100%;} .ExternalClass{width:100%;} </style> <table cellpadding="0" cellspacing="0" bgcolor="#ffffff"> <tr> <td width="550" valign="top" align="left"> <table cellpadding="0" cellspacing="0" width="500"> <tr> <td colspan="3"><img src="http://mail.yimg.com/nq/assets/sharedmessages/v1/us/logo.gif" width="292" height="51" style="display:block;" border="0" alt="Yahoo! Mail"></td> </tr> <tr> <td rowspan="3" width="1" bgcolor="#c7c4ca"></td> <td width="498" height="1" bgcolor="#c7c4ca"></td> <td rowspan="3" width="1" bgcolor="#c7c4ca"></td> </tr> <tr> <td width="498" valign="top" align="left"> <table cellpadding="0" cellspacing="0"> <tr> <td width="498" bgcolor="#61399d" align="left" valign="top"> <table cellspacing="0" cellpadding="0"><tr><td height="24"></td></tr></table> <div style="font-family:Arial, Helvetica, sans-serif;font-size:23px;line-height:27px;margin-bottom:10px;color:#ffffff;margin-left:15px;"><span style="color:#ffffff;text-decoration:none;font-weight:bold;line-height:27px;">Välkommen till Yahoo! Mail.</span></div> <div style="font-family:Arial, Helvetica, sans-serif;font-size:22px;line-height:26px;margin-bottom:1px;color:#ffffff;margin-left:15px;margin-bottom:7px;margin-right:15px;">Ansluta och dela går snabbt och enkelt och är tillgängligt överallt.</div> </td> </tr> <tr> <td><img src="http://mail.yimg.com/nq/assets/sharedmessages/v1/all/b1.gif" width="498" height="18" style="display:block;" border="0"></td> </tr> </table> <table cellpadding="0" cellspacing="0" width="498"> <tr> <td width="292" valign="top"> <table cellpadding="0" cellspacing="0"> <tr> <td><img src="http://mail.yimg.com/nq/assets/sharedmessages/v1/all/grad.gif" width="292" height="9" style="display:block;"></td> </tr> <tr> <td width="292" bgcolor="#ffffff" align="left" valign="top"> <table cellspacing="0" cellpadding="0"><tr><td height="11"></td></tr></table> <div style="margin-left:15px;"> <div style="font-family:Arial, Helvetica, sans-serif;font-size:14px;line-height:18px;color:#333333;margin-bottom:11px;font-weight:bold;">Det är lätt som en plätt att komma igång.</div> <table cellpadding="0" cellspacing="0" width="267"> <tr> <td width="16" align="left" valign="top"><div style="font-family:Arial, Helvetica, sans-serif;font-size:14px;line-height:16px;color:#61399d;margin-bottom:9px;font-weight:bold;">1. </div></td> <td align="left" valign="top"><div style="font-family:Arial, Helvetica, sans-serif;font-size:13px;line-height:16px;color:#61399d;margin-bottom:9px;"><a rel="nofollow" target="_blank" href="http://us-mg999.mail.yahoo.com/neo/launch?action=contacts" style="text-decoration:underline;color:#61399d;"><span>Lägg till alla dina kontakter på en plats</span></a>.</div></td> </tr> <tr> <td align="left" valign="top"><div style="font-family:Arial, Helvetica, sans-serif;font-size:14px;line-height:16px;color:#61399d;margin-bottom:9px;font-weight:bold;">2. </div></td> <td align="left" valign="top"><div style="font-family:Arial, Helvetica, sans-serif;font-size:13px;line-height:16px;color:#61399d;margin-bottom:9px;"><a rel="nofollow" target="_blank" href="http://mrd.mail.yahoo.com/themes" style="text-decoration:underline;color:#61399d;"><span>Anpassa din nya inkorg</span></a>.</div></td> </tr> <tr> <td align="left" valign="top"><div style="font-family:Arial, Helvetica, sans-serif;font-size:14px;line-height:16px;color:#61399d;margin-bottom:9px;font-weight:bold;">3. </div></td> <td align="left" valign="top"><div style="font-family:Arial, Helvetica, sans-serif;font-size:13px;line-height:16px;color:#61399d;"><a rel="nofollow" target="_blank" href="http://se.overview.mail.yahoo.com/mobile" style="text-decoration:underline;color:#61399d;"><span>Anslut överallt på dina mobila enheter</span></a>.</div></td> </tr> </table> </div> </td> </tr> <tr><td height="13"></td></tr> </table> </td> <td width="196" valign="top"> <table cellpadding="0" cellspacing="0"> <tr> <td width="1" bgcolor="#fbfbfd" valign="top"><img src="http://mail.yimg.com/nq/assets/sharedmessages/v1/all/g1.gif" width="1" height="21" style="display:block;"></td> <td width="1" bgcolor="#f5f6fa" valign="top"><img src="http://mail.yimg.com/nq/assets/sharedmessages/v1/all/g2.gif" width="1" height="21" style="display:block;"></td> <td width="1" bgcolor="#e8eaf1" valign="top"><img src="http://mail.yimg.com/nq/assets/sharedmessages/v1/all/g3.gif" width="1" height="21" style="display:block;"></td> <td width="1" bgcolor="#d4d4d4"></td> <td width="186" bgcolor="#f0f0f0" align="left" valign="top"> <table cellspacing="0" cellpadding="0"><tr><td height="3"> </td></tr></table> <div style="margin-left:11px;"> <div style="font-family:Arial, Helvetica, sans-serif;font-size:13px;line-height:16px;color:#333333;margin-bottom:9px;"><b>Info för dig:</b></div> <div style="font-family:Arial, Helvetica, sans-serif;font-size:12px;color:#43494e;line-height:18px;margin-bottom:10px;"> Yahoo!-ID och e-postadress:<br /> <div style="font-family:Arial, Helvetica, sans-serif;font-size:12px;color:#43494e;line-height:18px;"> Håll ditt konto och inställningar aktuella. <br><a rel="nofollow" target="_blank" href="https://edit.yahoo.com/config/eval_profile" style="text-decoration:underline;color:#61399d;"><span>Mitt konto</span></a> </div> </div> <table cellspacing="0" cellpadding="0"><tr><td height="20"></td></tr></table> </td> <td width="1" bgcolor="#dbdbdb"></td> <td width="1" bgcolor="#ced2de"></td> <td width="1" bgcolor="#dbdfed"></td> <td width="1" bgcolor="#e8ebf3"></td> <td width="1" bgcolor="#f3f4f9"></td> <td width="1" bgcolor="#fafbfc"></td> </tr> <tr> <td colspan="11"><img src="http://mail.yimg.com/nq/assets/sharedmessages/v1/all/b2.gif" width="196" height="8" style="display:block;" border="0"></td> </tr> <tr><td height="13"></td></tr> </table> </td> <td width="10"></td> </tr> </table> </td> </tr> <tr> <td width="498" height="1" bgcolor="#c7c4ca"></td> </tr> </table> <table cellpadding="0" cellspacing="0" width="500"> <tr> <td align="center" valign="top"> <table cellspacing="0" cellpadding="0"><tr><td height="10"></td></tr></table> <div style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:18px;margin-bottom:10px;"> <a rel="nofollow" target="_blank" href="http://info.yahoo.com/legal/se/yahoo/utos.html" style="text-decoration:underline;color:#61399d;">Yahoo! Villkor för användning</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a rel="nofollow" target="_blank" href="http://info.yahoo.com/legal/se/yahoo/mail/atos.html" style="text-decoration:underline;color:#61399d;">Yahoo! Mail –Villkor för användning</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a rel="nofollow" target="_blank" href="http://info.yahoo.com/privacy/se/yahoo/details.html" style="text-decoration:underline;color:#61399d;">Yahoo! Sekretesspolicy</a> </div> </td> </tr> <tr> <td align="left" valign="top"> <div style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:14px;color:#545454;margin-left:16px;margin-right:14px;">Var god svara inte på detta meddelande. Detta är ett servicemeddelande som rör din användning av Yahoo! Mail. Om du vill veta mer om Yahoo!s användning av personlig information, inklusive användning av webb-beacons i HTML-baserad e-post, kan du läsa vår Yahoo! Sekretesspolicy. Yahoo!s adress är 701 First Avenue, Sunnyvale, CA 94089, USA.<br /><br />RefID: lp-1037111</div> </td> </tr> </table> </td> </tr> </table> <img width="1" height="1" src="http://pclick.internal.yahoo.com/p/s=2143684696"> </body> </html>` 

而试图提取数据的python代码如下所示。

 >>> import sqlite3 >>> conn = sqlite3.connect('C:/temp/Mobils/export/com.yahoo.mobile.client.android.mail/databases/mail.db') >>> c = conn.cursor() >>> conn.row_factory=sqlite3.Row >>> c.execute('select body from messages_1 where _id=7') <sqlite3.Cursor object at 0x0000000001FB78F0> >>> r = c.fetchone() >>> r.keys() ['body'] >>> print(r['body']) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python32\lib\encodings\cp850.py", line 19, in encode return codecs.charmap_encode(input,self.errors,encoding_map)[0] UnicodeEncodeError: 'charmap' codec can't encode character '\u2013' in position 9629: character maps to <undefined> >>> 

有没有人有任何想法如何打印/写这个文件。 是的,我知道这是打印到标准输出,但当我尝试写入文件时,我得到相同的UnicodeEncodeError。 我尝试了文件对象的写入方法和print(r['body'], file=f)

当您打开要写入的文件时,使用可处理所有字符的特定编码打开它。

 with open('filename', 'w', encoding='utf-8') as f: print(r['body'], file=f) 

也许有点晚回复。 我今天遇到同样的问题。 我发现,在Windows上,您可以将控制台编码器更改为utf-8或其他可以表示您的数据的编码器。 然后你可以打印到sys.stdout

首先,在控制台中运行以下代码:

 chcp 65001 set PYTHONIOENCODING=utf-8 

然后,启动python做任何你想要的。

虽然Python 3使用Unicode进行处理,但是您在其中运行的Windows控制台或POSIX tty不支持。 因此,无论何时print或以其他方式将Unicodestring发送到stdout ,并将其附加到控制台/ tty,Python都必须对其进行编码。

错误信息间接告诉你Python试图使用什么字符集:

  File "C:\Python32\lib\encodings\cp850.py", line 19, in encode 

这意味着charset是cp850

你可以testing一下,或者你自己,这个字符集只是通过'\u2013'.encode('cp850')没有合适的字符。 或者你可以在网上查找cp850(例如,在维基百科 )。

Python可能猜错了,你的控制台真的是UTF-8。 (在这种情况下,只需手动设置sys.stdout.encoding='utf-8' 。)也可能是您的控制台被设置为UTF-8,但做错了。 (在这种情况下,您可能想要在superuser.com上进行跟进。)

但是,如果没有什么错,就不能打印那个字符。 您将不得不用一个非严格的error handling程序手动编码它。 例如:

 >>> '\u2013'.encode('cp850') UnicodeEncodeError: 'charmap' codec can't encode character '\u2013' in position 0: character maps to <undefined> >>> '\u2013'.encode('cp850', errors='replace') b'?' 

那么,如何打印不会在控制台上打印的string呢?

可以用这样的东西replace每个printfunction:

 >>> print(r['body'].encode('cp850', errors='replace').decode('cp850')) ? 

…但是这个过程会非常繁琐。

简单的事情就是在sys.stdout上设置error handling程序:

 >>> sys.stdout.errors = 'replace' >>> print(r['body']) ? 

对于打印到一个文件,事情是几乎相同的,除了你不必事后设置f.errors ,你可以在施工时进行设置。 而不是这个:

 with open('path', 'w', encoding='cp850') as f: 

做这个:

 with open('path', 'w', encoding='cp850', errors='replace') as f: 

…或者,当然,如果你可以使用UTF-8文件,就这样做,正如Mark Ransom的回答所示:

 with open('path', 'w', encoding='utf-8') as f: