2011-03-26 20 views
31

我剛剛從python 3.1更新到python 3.2(格式化高清),我的一個腳本停止工作。它給了我標題中的錯誤。TypeError:POST數據應該是字節或可迭代的字節。它不能str

我會自己修復它,但我什至不知道什麼是一個可迭代的字節是哈哈。我嘗試了類型轉換(數據),但是這也不起作用。 TypeError:沒有編碼的字符串參數

url = "http://example.com/index.php?app=core&module=global&section=login&do=process" 
values = {"username" : USERNAME, 
      "password" : PASSWORD} 
data = urllib.parse.urlencode(values) 
req = urllib.request.Request(url, data) 
urllib.request.urlopen(req) 

它在最後一行崩潰。

工程在3.1,而不是3.2

回答

43

你的確在嘗試將字符串轉換爲字節基本上是正確的,但你做了錯誤的方式。 Python沒有類型轉換(所以你沒有類型轉換)。

做到這一點的方法是編碼的文本數據轉換爲字節數據,這些數據與編碼功能做:

binary_data = data.encode('encoding') 

什麼「編碼」應該是依賴。你應該在這裏使用'ascii'。如果你的字符不是ASCII,那麼你需要使用另一種編碼,通常是'utf8',但是你還需要告訴接收的網絡服務器它是UTF-8。它可能也不需要UTF8,但是你必須問它,而且它變得越來越複雜。 :-)

+14

這是一個很好的答案,但我認爲,如果它包括修正還可以提高碼。不清楚數據來自何處以及在哪裏提供binary_data。 – 2013-12-12 20:13:39

+1

@rodarmor:在上面的例子中,'data'是變量'data'。在需要轉換的數據的地方提供'binary_data'。 – 2013-12-12 20:29:40

+1

我添加了一個可以讓OP的例子工作的線,你可以仔細檢查一下,以確保它正確嗎? – 2013-12-12 20:41:26

7

@恩德斯,我知道這是一個老問題,但我想解釋一些與這個問題鬥爭的人的更多事情。

它特別是這行代碼在這裏:

data = urllib.parse.urlencode(values) 

,您有問題,因爲你試圖對數據進行編碼:值(用urlencode)。

如果你指的urllib.parse文檔滾動至底部,查找用urlencode做:https://docs.python.org/3/library/urllib.parse.html <〜你會看到你正在嘗試編碼您的用戶名/密碼成數據串:

Convert a mapping object or a sequence of two-element tuples, which may contain str or bytes objects, to a percent-encoded ASCII text string. If the resultant string is to be used as a data for POST operation with the urlopen() function, then it should be encoded to bytes, otherwise it would result in a TypeError.

也許你在這裏想要做的是對你的用戶/密碼做一些加密,但我並不認爲這是正確的方式。如果是這樣,那麼你可能需要確保接收端(你的url的目的地)知道你正在用這個編碼你的用戶/密碼。

更新的方法是使用強大的請求庫。他們有很普通的身份驗證協議的兼容性:http://docs.python-requests.org/en/master/user/authentication/

在這種情況下,我會做這樣的事情:

requests.get(url, auth=('user', 'pass')) 
相關問題