web-dev-qa-db-fra.com

Python 3 urllib produit TypeError: POST les données doivent être des octets ou un itérable d'octets. Elles ne peuvent pas être de type str

J'essaie de convertir le code Python 2.7) en code Python 3) et je reçois une erreur de type du module de demande urllib.

J'ai utilisé l'outil 2to3 Python intégré pour convertir l'urllib de travail ci-dessous et urllib2 Python 2.7 code:

import urllib2
import urllib

url = "https://www.customdomain.com"
d = dict(parameter1="value1", parameter2="value2")

req = urllib2.Request(url, data=urllib.urlencode(d))
f = urllib2.urlopen(req)
resp = f.read()

La sortie du module 2to3 était le code Python 3 ci-dessous:

import urllib.request, urllib.error, urllib.parse

url = "https://www.customdomain.com"
d = dict(parameter1="value1", parameter2="value2")

req = urllib.request.Request(url, data=urllib.parse.urlencode(d))
f = urllib.request.urlopen(req)
resp = f.read()

Lorsque le code Python 3 est exécuté, l'erreur suivante est générée:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-56-206954140899> in <module>()
      5 
      6 req = urllib.request.Request(url, data=urllib.parse.urlencode(d))
----> 7 f = urllib.request.urlopen(req)
      8 resp = f.read()

C:\Users\Admin\Anaconda3\lib\urllib\request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    159     else:
    160         opener = _opener
--> 161     return opener.open(url, data, timeout)
    162 
    163 def install_opener(opener):

C:\Users\Admin\Anaconda3\lib\urllib\request.py in open(self, fullurl, data, timeout)
    459         for processor in self.process_request.get(protocol, []):
    460             meth = getattr(processor, meth_name)
--> 461             req = meth(req)
    462 
    463         response = self._open(req, data)

C:\Users\Admin\Anaconda3\lib\urllib\request.py in do_request_(self, request)
   1110                 msg = "POST data should be bytes or an iterable of bytes. " \
   1111                       "It cannot be of type str."
-> 1112                 raise TypeError(msg)
   1113             if not request.has_header('Content-type'):
   1114                 request.add_unredirected_header(

TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str.

J'ai également lu deux autres tickets ( ticket1 et ticket2 ) qui mentionnaient l'encodage de la date.

Lorsque j'ai changé la ligne f = urllib.request.urlopen(req) en f = urllib.request.urlopen(req.encode('utf-8')) j'ai reçu l'erreur suivante: AttributeError: 'Request' object has no attribute 'encode'

Je ne sais pas comment faire fonctionner le code Python 3. Pourriez-vous m'aider?

27
Greg

À partir de docs Notez que la sortie des paramètres de urlencode est codée en octets avant d'être envoyée à urlopen en tant que données:

data = urllib.parse.urlencode(d).encode("utf-8")
req = urllib.request.Request(url)
with urllib.request.urlopen(req,data=data) as f:
    resp = f.read()
    print(resp)
44
Padraic Cunningham

Essaye ça:

url = 'https://www.customdomain.com'
d = dict(parameter1="value1", parameter2="value2")

f = urllib.parse.urlencode(d)
f = f.encode('utf-8')

req = urllib.request.Request(url, f)

Votre problème réside dans la façon dont vous gérez le dictionnaire.

5
Leb

J'ai utilisé python module de requêtes avec ZOHO CRM API V2. Cela a fonctionné sans aucun problème. Voici un exemple de code de travail avec une requête GET:

import json
import requests

# API methods - https://www.zoho.com/crm/developer/docs/api/api-methods.html
# getrecords API Call
module_name = 'Deals'
authtoken = '*****'
api_url = "https://crm.zoho.com/crm/private/json/"+module_name+"/getRecords?authtoken="+authtoken+"&scope=crmapi&fromIndex=1&toIndex=2"

# GET Request
request_response = requests.get(
    url=api_url
    )
print(json.dumps(json.loads(request_response.text), sort_keys=True, indent=4, separators=(",", ": ")))
json_response = json.loads(request_response.text)
0
Dasitha Abeysinghe