套接字 400 错误 header

400 error header with sockets

我正在创建一个论坛状态采集器。但是我想用套接字从论坛上抓取数据。所以我正在写套接字 a header。但是有400错误。所以我制作了一个测试脚本来进行检查,但仍然出现错误。

import socket
s = socket.socket()
s.connect(("198.57.47.136", 80))
header = """
GET / HTTP/1.1\r\n
Host: httn
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60\r\n
Accept-Encoding: gzip, deflate, lzma, sdch\r\n
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6\r\n
"""
s.send(header)
print s.recv(10000)

哪个returns

HTTP/1.1 400 Bad Request
Server: nginx
Date: Thu, 01 Jan 2015 21:43:47 GMT
Content-Type: text/html
Content-Length: 166
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

可能是您请求的格式有问题。

首先,您的 HTTP 请求以换行符开头。此外,HTTP 请求中的行必须用 \r\n 分隔,而 Python 多行字符串只有 \n。但是因为你在其中一些(不是全部)中有文字 \r\n 它是一团糟。

最后,header 必须以空行结尾。

我的建议是使用没有任何行结尾的字符串列表,然后加入它们:

header_lines = [
 "GET / HTTP/1.1",
 "Host: httn",
 "Connection: keep-alive",
 ...
]

header = "\r\n".join(header_lines) + "\r\n\r\n"

请注意,由于 str.join() 未添加最终 EOL,因此您必须添加其中两个以包括强制空行。

A multi-line Python 字符串为每一行添加一个额外的 \n。注:

>>> s = '''
... Host: rile5.com\r\n
... '''
>>>
>>> s
'\nHost: rile5.com\r\n\n'

有一个额外的第一行,每行 两个 \n。这有效,但不适用于您使用的原始 IP 地址:

import socket
s = socket.socket()
s.connect(("rile5.com", 80))
header = b"""\
GET / HTTP/1.1\r
Host: rile5.com\r
Connection: keep-alive\r
Cache-Control: max-age=0\r
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r
User-Agent: Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60\r
Accept-Encoding: gzip, deflate, lzma, sdch\r
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6\r
\r
"""
s.sendall(header)
print(s.recv(10000))

注意左引号后的额外斜线。这会抑制初始换行符。

header = b"""\

还要注意末尾的额外空行。这是必需的,以便服务器知道 header 已完成。

为什么不直接使用 urllib.request