Python HTTP 总是 301 使用套接字

Python HTTP always 301 using sockets

我编写了一个简单的程序,使用 python 从网站获取一些信息。 但是当我 运行 下面的代码时,它总是 returns 下面的 301 信息。同时,我的浏览器可以轻松访问该网站。 请告诉我为什么会发生这种情况以及如何改进我的代码以避免出现此问题。

HTTP/1.1 301 Moved Permanently
Date: Tue, 28 Aug 2018 14:26:20 GMT
Server: Apache
Referrer-Policy: origin-when-cross-origin
Location: https://www.ncbi.nlm.nih.gov/
Content-Length: 237
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a         href="https://www.ncbi.nlm.nih.gov/">here</a>.</p>
</body></html>

import socket

searcher = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
searcher.connect(("www.ncbi.nlm.nih.gov", 80))
cmd = "GET https://www.ncbi.nlm.nih.gov/ HTTP/1.0\r\n\r\n".encode()
searcher.send(cmd)
while True:
    data = searcher.recv(512)
    if len(data)<1: break
    print(data.decode())
searcher.close()

您收到 301,因为网站正在重定向到 https 网站。

我不知道是否必须使用套接字,但如果不是,您可以使用请求,它是一个易于使用的库,用于执行 http 请求:

import requests

req = requests.get("http://www.ncbi.nlm.nih.gov")
html = req.text

有了这个,301 无论如何都会执行,但是它是透明的。

如果你想用套接字来做,你应该手动添加"ssl layer":

import socket
import ssl

searcher = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
searcher.connect(("www.ncbi.nlm.nih.gov", 443))
searcher = ssl.wrap_socket(searcher, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_SSLv23)
cmd = "GET https://www.ncbi.nlm.nih.gov/ HTTP/1.0\r\n\r\n".encode()
searcher.send(cmd)
while True:
    data = searcher.recv(512)
    if len(data) < 1: break
    print(data.decode())
searcher.close()