10

lxml を使用して POST メソッド フォームを送信しようとすると、TypeError が発生します。これは、このエラーを発生させる最小限の例です:

>>> 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.

オンラインで正確なエラーを見つけましたが、このように lxml 内から生成されたエラーは見たことがありません。これがバグなのか、予想される動作なのか、それを回避する方法を知っている人はいますか?

4

3 に答える 3

1

https://github.com/lxml/lxml/pull/122/filesから:

「python3 では、urlopen は POST データのバイト ストリームを想定しています。このパッチは、送信前にデータを utf-8 でエンコードします。」src/lxml/html/__init__.py の 918 行目を変更します。

data = urlencode(values)

data = urlencode(values).encode('utf-8')
于 2014-02-21T21:58:51.187 に答える
0

それはPython 3なので、あなたは書くべきです

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

また

form.fields['your_name'] = 'Morphit'.encode('utf-8')
于 2013-12-14T22:03:47.510 に答える
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))
于 2015-01-25T08:51:41.183 に答える