带套接字的400错误标头

时间:2015-01-01 21:47:06

标签: python sockets

我正在创建一个论坛状态抓取器。但我想使用套接字从论坛中获取数据。所以我在socket上写了一个标题。但是有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)

返回

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>

2 个答案:

答案 0 :(得分:1)

可能问题在于您的请求格式。

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

最后,标题必须以空行结束。

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

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

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

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

答案 1 :(得分:1)

多行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"""\

另请注意末尾的额外空白行。这是必需的,因此服务器知道标头已完成。

为什么不使用urllib.request