2016-01-24 48 views
-2

我有一個非文字字符串,它以在線方式從打印文檔的標題以編程方式獲得。Win32print結果的字符串編碼

當我試圖把它提交到MongoDB中,我得到:

bson.errors.InvalidStringData: strings in documents must be valid UTF-8: 'wxPython: Windows Styles and Events Hunter \xab The Mouse Vs. The Python' 

字符串檢索代碼:

for printStats in printers: 

    handle = win32print.OpenPrinter(printStats[2]) 
    queued = win32print.EnumJobs(handle, 0, -1, 1) 

    for printJob in queued: 

     username = printJob['pUserName'] 
     computer = printJob['pMachineName'] 
     document = printJob['pDocument'] 
     identity = printJob['JobId'] 
     jobstate = printJob['Status'] 

print document 
> "wxPython: Windows Styles and Events Hunter « The Mouse Vs. The Python" 
+0

什麼類型的數據庫和拋出的異常是什麼? –

+0

如何以base64編碼形式存儲/恢復此字符串? – nsilent22

+0

MongoDB將字符串存儲爲UTF-8。 Python驅動程序允許您傳遞UTF-8編碼的字符串或Unicodes。這聽起來像你的字符串既不是。你必須先理解編碼,然後才能拋出'encode'和'decode'。例外是希望從表中排除非ASCII。 –

回答

0

從其他的答案您的意見,我可以看到你的錯誤是:

bson.errors.InvalidStringData: strings in documents must be valid UTF-8: 'wxPython: Windows Styles and Events Hunter \xab The Mouse Vs. The Python' 

由於«被編碼爲\xab,這意味着該字符串很可能是在iso-8995-1,iso-8995-15,windows-1252/latin-1中編碼的。這很可能與您的機器的語言環境有關。

您只需將它傳遞給MongoDB中,支持Unicode字符串之前(因爲你斷言它不限於ASCII)解碼:

document = printJob['pDocument'].decode("latin-1") 

>>> print type(document) 
<type 'unicode'> 

您現在可以通過document到Python的MongoDB的驅動程序。

爲使代碼便於攜帶,您可以使用編解碼器別名mbcs(取代'latin-1')。 mbcs會自動轉換爲配置的Windows區域設置(感謝@roeland)

+0

字符串被編碼 - 它來自哪裏並不重要。我更新了我的僞代碼以符合您的代碼。我非常懷疑'printJob ['pDocument']'的編碼會在你的機器上發生變化。首先嚐試一下我的例子,然後考慮如何使你的代碼變得可移植 –

+0

我猜想這個字符串將會在該機器的本地編碼中,這個編碼將通過別名「mbcs」。 – roeland

+0

感謝提示@roeland!我不知道這個別名是否存在。我會更新我的回答 –

0

編碼的默認模式爲'strict',這將拋出一個錯誤。

>>> s = u"wxPython: Windows Styles and Events Hunter « The Mouse Vs. The Python" 
>>> s.encode('ascii') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xab' in position 43: ordinal not in range(128) 

如果您的數據庫只接受ASCII,您別無選擇,只能做有損編碼。在'ignore'模式不能被編碼的所有字節被跳過:

>>> s.encode('ascii', 'ignore') 
'wxPython: Windows Styles and Events Hunter The Mouse Vs. The Python' 

'replace'模式下,它們被取代?人物:

>>> s.encode('ascii', 'replace') 
'wxPython: Windows Styles and Events Hunter ? The Mouse Vs. The Python' 

最後,還有'xmlcharrefreplace'

>>> s.encode('ascii', 'xmlcharrefreplace') 
'wxPython: Windows Styles and Events Hunter &#171; The Mouse Vs. The Python' 
+0

@MalikBrahimi不在ASCII中 – timgeb

+0

因爲ASCII不能編碼不在範圍內的字節(128)。 – timgeb

+0

@MalikBrahimi可能會看到這個:https://www.youtube.com/watch?v=Mx70n1dL534他們在第25分鐘談論你的確切問題。 – timgeb