无法使用套接字获取所需的内容

时间:2018-10-27 20:45:36

标签: python python-3.x sockets web-scraping

我正在尝试使用sockethere获取可见的内容,但是不幸的是,我在执行脚本时遇到错误。因为我刚开始使用socket进行编码,所以我不知道我要去哪里哪里。

我的代码:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_ip = socket.gethostbyname('data.pr4e.org')
s.connect((host_ip,80))
cmd = "GET http://data.pr4e.org/romeo.txt HTTP/1.0\n\n".encode()
s.send(cmd)

while True:
    data = s.recv(1024)
    if (len(data) <1 ):
        break
    print(data.decode())
s.close()

我遇到的错误:

400 Bad Request

Your browser sent a request that this server could not understand.

2 个答案:

答案 0 :(得分:1)

我可以通过在请求命令的末尾添加\r\n\r\n而不是原始的\n\n来获得所需的结果:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostbyname('data.pr4e.org'), 80))
s.sendall("GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n".encode())
print(s.recv(1024))

输出:

...
Content-Type: text/plain\r\n\r\nBut soft what light through yonder window breaks\nIt is the east and Juliet is the sun\nArise fair sun and kill the envious moon\nWho is already sick and pale with grief\n'

答案 1 :(得分:1)

这里有多个问题:

  1. 除非将http://data.pr4e.org放在GET之后(见RFC 7230),否则不常见,除非与代理交谈。通常,您将编写GET /romeo.txt并在separate Host: data.pr4e.org header中提供主机名。服务器需要支持您使用的表单,但是它们可能会违反标准并使其窒息。如果您声称使用的HTTP / 1.0更严格且forbids this form unless talking to a proxy,则很有可能。
  2. 没有人再使用HTTP / 1.0。所有现代浏览器和其他HTTP客户端都使用HTTP / 1.1或HTTP / 2。某些服务器将支持HTTP / 1.0,但这不是强制性的。请注意,即使您将完整的URL放在GET之后,也要使用HTTP / 1.1 makes the Host: header mandatory
  3. HTTP / 1.0使用\r\n(“ CRLF”)作为换行符(请参阅RFC 1945),因此可能无法始终理解\n。同样,某些服务器将正确处理它,但是它不符合要求。 carried over to HTTP/1.1已使用CRLF。
  4. print(data.decode())将在data的末尾添加一个额外的换行符。如果TCP分割了一个较大的HTTP响应,使得recv()返回多个非空字符串,这可能会成为问题。请改用print(data.decode(), end='')