2012-10-31 6 views
10

Ich versuche, eine POST-Methode Formular mit Lxml und ich erhalte einen TypeError. Dies ist ein minimales Beispiel, das diesen Fehler auslöst:POST-Methode Formular in lxml löst TypeError mit 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. 

ich online woanders den genauen Fehler gefunden haben, aber ich habe nicht gesehen, es von innen lxml wie diese erzeugt. Weiß jemand, ob dies ein Fehler oder erwartetes Verhalten ist und wie man es umgehen kann?

+1

Ich habe den gleichen Fehler .. es ist wirklich ein Bug scheint, weil es interne Management ist von str/Unicode/Bytes. – abourget

+3

Als Referenz hat Morphit einen Fehler an [lxml's bug tracker] gesendet (https://bugs.launchpad.net/lxml/+bug/1074996), [hat eine Pull-Anfrage vorgeschlagen] (https://github.com/lxml/ lxml/pull/122) um das Patch zu reparieren, wurde es sogar basierend auf Feedback verbessert. Leider wartet die Pull-Anfrage immer noch darauf, zusammengeführt zu werden! –

+0

@Morphit: Sie könnten hier Ihre vorgeschlagene Pull-Anfrage als Antwort hinzufügen. Akzeptiere diese Antwort, so dass dies keine unbeantwortete Frage mehr ist. – user1251007

Antwort

1

Von https://github.com/lxml/lxml/pull/122/files schreiben:

„In python3, urlopen erwartet einen Bytestrom dies für die POST-Daten. Patch codiert die Daten in utf-8 vor der Übertragung. " In src/lxml/html/__ init__.py, ändern 918,

data = urlencode(values) 

zu

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

Es ist Python 3, so sollten Sie

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

oder

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

Feldwerte sind nicht wichtig. Versuchen Sie 'python3 -c 'import lxml.html; lxml.html.submit_form (lxml.html.fromstring ("" form form = POST action = "http: //doesnot.matter"> "" ") .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)) 
Verwandte Themen