在 Python 3 中使用套接字获取 400 错误请求错误

Sri*_*uri 4 python sockets networking python-3.x web

我刚开始使用 Python 3.6.1 中的 Python Web 数据。我正在学习套接字,但我的代码有问题,我无法弄清楚。我的代码中的网站工作正常,但是当我运行此代码时,我收到 400 Bad Request 错误。我不太确定我的代码有什么问题。提前致谢。

import socket

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

mysock.connect(('data.pr4e.org', 80))

mysock.send(('GET http://data.pr4e.org/romeo.txt HTTP/1.0 \n\n').encode())

while True:
    data = mysock.recv(512)
    if ( len(data) < 1 ):
        break
    print (data)

mysock.close()
Run Code Online (Sandbox Code Playgroud)

Ste*_*ich 7

GET http://data.pr4e.org/romeo.txt HTTP/1.0 \n\n
Run Code Online (Sandbox Code Playgroud)

欢迎来到 HTTP 的美妙世界,大多数用户认为这是一个简单的协议,因为它是人类可读的,但实际上它可能是一个非常复杂的协议。鉴于您的上述要求,存在几个问题:

  • 路径不应该是完整的 URL,而应该是/romeo.txt. 只有在向代理发出请求时才会使用完整的 URL。
  • 行尾必须\r\n不是\n
  • HTTP/1.0行尾之前不应有空格。
  • 虽然 HTTP/1.1 只需要 Host 标头,但许多服务器(包括您尝试访问的服务器)也需要 HTTP/1.0,因为它们在同一 IP 地址上有多个主机名,并且需要区分您想要的名称。

考虑到这一点,您发送的数据应该改为

GET /romeo.txt HTTP/1.0\r\nHost: data.pr4e.org\r\n\r\n
Run Code Online (Sandbox Code Playgroud)

我已经测试过它与此修改完美配合。

但是,鉴于 HTTP 并不像看起来那么简单,我真的建议使用像访问目标的请求这样的库。如果这对您来说看起来开销太大,请研究HTTP 标准以正确实现它,而不是仅仅从一些示例中猜测 HTTP 的工作原理 - 并且猜测它是错误的。

另请注意,服务器对像您这样的损坏实现的宽容程度有所不同。因此,在某些软件升级后,曾经在一台服务器上工作的内容可能不适用于下一台服务器,甚至可能不适用于同一台服务器。使用一个健壮的、经过良好测试和维护的库,而不是自己做所有事情,也可能会在以后为您省去很多麻烦。