首页 > 解决方案 > 通过套接字python3获取页面

问题描述

我正在尝试通过 python 3 中的套接字代理获取页面。我首先连接到https://sslproxies.org上列出的代理,然后发送GET请求:

GET https://icanhazip.com HTTP/1.1\r\n

但它给出了一个错误,说:

HTTP Bad Request 400(数据无效)

所以我尝试通过使用来避免 Host 参数HTTP/1.0,但这也不起作用。

什么请求有效?

完整代码:

import socket

s = socket.socket()
host = "xx.xx.xx.xx"
port = 80
s.connect((host, port))
s.sendall("GET https://icanhazip.com HTTP/1.0\r\n".encode("utf-8"))

res = s.recv(10000)
while len(res) > 0:
    print(res)
    res = s.recv(10000)

标签: python-3.xsockets

解决方案


服务器是正确的:您正在发送一个错误的请求。不幸的是,您的请求有很多问题,这意味着没有简单的单一解决方案。绝对错误的是:

  • 没有结束标题分隔符(即空行\r\n)。
  • 没有Host标头,这是 HTTP/1.1 所必需的(正如您在示例中使用请求的样子),标准不需要,但大多数 HTTP/1.0 的服务器仍然需要(如您在实际代码中使用的那样) )。
  • 您不能只https://在请求中添加一个 url,并假设它会神奇地执行 https。相反,您需要连接到服务器,进行 SSL 握手,然后发送正确的 HTTP 请求,其中仅包含路径但不包含完整的 URL。连接到代理时(正如您似乎尝试的那样),您甚至需要添加一些 CONNECT 请求并在将套接字升级到 SSL 之前读取其响应。
  • 您假设您可以将端口 80 用于 HTTPS,但默认情况下使用端口 443,但是当连接到代理时,您实际上为 HTTP 和 HTTP 使用相同的端口,尽管它通常是 8000、8080 或类似的端口。
  • 也许更多。

简而言之:使用 HTTP 库。如果您不想使用一项研究 HTTP 标准并且不要只看示例(如果您到目前为止还这样做过)。


推荐阅读