【问题标题】:python3 HTTPConnection throws FileNotFoundErrorpython3 HTTPConnection 抛出 FileNotFoundError
【发布时间】:2013-10-17 07:59:28
【问题描述】:

我正在尝试使用 python3 http.client 创建一个 HTTPConnection。这是我的代码:

import http.client
import base64 
if __name__ == '__main__':
    username = "xx" # enter your username
    password = "xxx" # enter your password
    device_id = "00000000-00000000-00409DFF-FF7660EC" # enter device id of target 
    # Nothing below this line should need to be changed
    # ------------------------------------------------- 

    # create HTTP basic authentication string, this consists of 
    encodestring = '%s:%s' % (username, password)
    auth = base64.encodebytes(encodestring.encode('utf-8'))[:-1]
    # message to send to server
    message = """<sci_request version="1.0"> 
    <send_message> 
      <targets> 
        <device id="%s"/>
      </targets> 
      <rci_request version="1.1">
          <query_state/>
      </rci_request>
    </send_message>
    </sci_request>
    """%(device_id)
    webservice = http.client.HTTPConnection("login.etherios.com ", 80)
    # to what URL to send the request with a given HTTP method
    webservice.putrequest("POST", "/ws/sci")     
    # add the authorization string into the HTTP header
    webservice.putheader("Authorization", "Basic %s" % auth)
    webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
    webservice.putheader("Content-length", "%d" % len(message))
    webservice.endheaders()
    webservice.send(message)
    # get the response
    statuscode, statusmessage, header = webservice.getreply()
    response_body = webservice.getfile().read()
    # print the output to standard out
    print (statuscode, statusmessage)
    print (response_body)

我运行脚本时的错误信息是

FileNotFoundError: [Errno 2] No such file or directory

错误指向第 40 行 (webservice.endheaders()),我觉得这有点令人困惑。任何人都可以阐明错误消息吗?

这是完整的回溯:

In [47]: run import_sensor
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
/usr/lib/python3/dist-packages/IPython/utils/py3compat.py in execfile(fname, glob, loc)
     74     def execfile(fname, glob, loc=None):
     75         loc = loc if (loc is not None) else glob
---> 76         exec(compile(open(fname, 'rb').read(), fname, 'exec'), glob, loc)
     77 
     78     # Refactor print statements in doctests.

/home/markus/python/precirrr-py/precirr/import_sensor.py in <module>()
     38     webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
     39     webservice.putheader("Content-length", "%d" % len(message))
---> 40     webservice.endheaders()
     41     webservice.send(message)
     42     # get the response

/usr/lib/python3.3/http/client.py in endheaders(self, message_body)
   1055         else:
   1056             raise CannotSendHeader()
-> 1057         self._send_output(message_body)
   1058 
   1059     def request(self, method, url, body=None, headers={}):

/usr/lib/python3.3/http/client.py in _send_output(self, message_body)
    900             msg += message_body
    901             message_body = None
--> 902         self.send(msg)
    903         if message_body is not None:
    904             # message_body was not a string (i.e. it is a file), and

/usr/lib/python3.3/http/client.py in send(self, data)
    838         if self.sock is None:
    839             if self.auto_open:
--> 840                 self.connect()
    841             else:
    842                 raise NotConnected()

/usr/lib/python3.3/http/client.py in connect(self)
    816         """Connect to the host and port specified in __init__."""
    817         self.sock = socket.create_connection((self.host,self.port),
--> 818                                              self.timeout, self.source_address)
    819         if self._tunnel_host:
    820             self._tunnel()

/usr/lib/python3.3/socket.py in create_connection(address, timeout, source_address)
    415     host, port = address
    416     err = None
--> 417     for res in getaddrinfo(host, port, 0, SOCK_STREAM):
    418         af, socktype, proto, canonname, sa = res
    419         sock = None

FileNotFoundError: [Errno 2] No such file or directory

【问题讨论】:

  • HTTPConnection 构造函数中的主机名末尾是否真的有多余的空间?因为那应该在你到达endheaders之前给你一个gaierror或类似的。
  • 同时,您将在send 上获得TypeError;您不能通过套接字发送str;您必须将encode 发送到bytes。而getreply 将引发AttributeError,因为没有这样的方法。 (也许你的意思是getresponse?)
  • getfile 也是如此。没有这样的方法;你在从getresponse 得到的HTTPResponse 对象上调用read。你从哪里得到这个代码?如果它是从教程中复制的,您可能希望找到更好的教程……
  • 最后,能否给我们完整的回溯,而不是错误信息,以及你认为它在哪一行的描述?
  • @abarnert:感谢 cmets。我从网络服务的分销商那里得到了这个代码。它是为 python2 编写的,我将库更新为 python3 并在编码上做了一些工作并卡住了。看来重写比我原先想象的要复杂。

标签: python http python-3.x


【解决方案1】:

问题出在这里:

webservice = http.client.HTTPConnection("login.etherios.com ", 80)

"login.etherios.com " 末尾的多余空格表示它不是有效的 DNS 名称。例如:

>>> socket.getaddrinfo('login.etherios.com', 80, 0, socket.SOCK_STREAM)
[(2, 1, 6, '', ('108.166.22.160', 80))]
>>> socket.getaddrinfo('login.etherios.com ', 80, 0, socket.SOCK_STREAM)
gaierror: [Errno 8] nodename nor servname provided, or not known

(不友好的gaierror 正在被翻译为友好但不是很准确的FileNotFoundError 更远的链条,但这在这里并不重要。)


那么,为什么您会在webservice.endheaders() 中一直看到错误?好吧,Python 正试图在这里变得聪明。如果它立即打开套接字,然后在您提供时一次发送一行数据,而将套接字留在中间,它会浪费您机器上的 CPU 和网络资源,可能在远程服务器和/或路由器上,甚至可能在互联网上。最好只打开连接并立即发送整个请求(或者,当您有很多数据时,至少到标头的末尾)。因此,Python 试图为您做到这一点。这意味着它不会意识到你给了它不好的信息,直到它真正尝试使用它。

【讨论】:

  • 非常感谢您的帮助。一个很小的空间和这样的影响。修复此问题后,我能够正确设置编码,相应地调整方法名称,它终于奏效了。
猜你喜欢
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 2021-11-10
  • 2020-03-16
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
相关资源
最近更新 更多