2012-10-31 6 views
10

Sto provando a inviare un modulo di metodo POST utilizzando lxml e sto ricevendo un errore TypeError. Questo è un esempio minimo che solleva questo errore:Il modulo POST in lxml genera TypeError con submit_form

>>> import lxml.html 
>>> page = lxml.html.parse("http://www.webcom.com/html/tutor/forms/start.shtml") 
>>> form = page.getroot().forms[0] 
>>> form.fields['your_name'] = 'Morphit' 
>>> result = lxml.html.parse(lxml.html.submit_form(form)) 
    Traceback (most recent call last): 
      File "<stdin>", line 1, in <module> 
      File "/usr/lib/python3.3/site-packages/lxml/html/__init__.py", line 887, in submit_form 
       return open_http(form.method, url, values) 
      File "/usr/lib/python3.3/site-packages/lxml/html/__init__.py", line 907, in open_http_urllib 
       return urlopen(url, data) 
      File "/usr/lib/python3.3/urllib/request.py", line 160, in urlopen 
       return opener.open(url, data, timeout) 
      File "/usr/lib/python3.3/urllib/request.py", line 471, in open 
       req = meth(req) 
      File "/usr/lib/python3.3/urllib/request.py", line 1183, in do_request_ 
       raise TypeError(msg) 
      TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str. 

ho trovato l'errore esatto un altro sito, ma io non l'ho visto generata dall'interno lxml come questo. Qualcuno sa se questo è un bug, o un comportamento atteso e come aggirarlo?

+1

Ho lo stesso problema .. è davvero sembra come un insetto, perché è la gestione interna di str/unicode/byte. – abourget

+3

Per riferimento, Morphit ha inviato un bug a [lxml's bug tracker] (https://bugs.launchpad.net/lxml/+bug/1074996), [ha proposto una richiesta di pull] (https://github.com/lxml/ lxml/pull/122) per correggere la patch, anche migliorata in base al feedback. Purtroppo, la richiesta pull è ancora in attesa di essere unita! –

+0

@Morphit: è possibile aggiungere la richiesta di pull proposta come risposta qui. Accetta questa risposta, in modo che questa non sia più una domanda senza risposta. I valori di campo – user1251007

risposta

1

Da https://github.com/lxml/lxml/pull/122/files:.

"In python3, urlopen si aspetta un flusso di byte per i dati POST questo patch codifica i dati in utf-8 prima della trasmissione. " In src/lxml/html/__ init__.py, cambiare la linea 918,

data = urlencode(values) 

a

data = urlencode(values).encode('utf-8') 
0

È Python 3, così si dovrebbe scrivere

form.fields['your_name'] = b'Morphit' 

o

form.fields['your_name'] = 'Morphit'.encode('utf-8') 
+0

non contano. Prova 'python3 -c 'import lxml.html; lxml.html.submit_form (lxml.html.fromstring ("" "

" "" .forms [0]) '' – jfs

0
def myopen_http(method, url, values): 
    if not url: 
     raise ValueError("cannot submit, no URL provided") 
    ## FIXME: should test that it's not a relative URL or something 
    try: 
     from urllib import urlencode, urlopen 
    except ImportError: # Python 3 
     from urllib.request import urlopen 
     from urllib.parse import urlencode 
    if method == 'GET': 
     if '?' in url: 
     url += '&' 
     else: 
     url += '?' 
     url += urlencode(values) 
     data = None 
    else: 
     data = urlencode(values).encode('utf-8') 

    return urlopen(url, data) 

result = lxml.html.parse(lxml.html.submit_form(form, open_http=myopen_http))