【问题标题】:Can't fetch desired content using socket无法使用套接字获取所需的内容
【发布时间】:2018-10-27 20:45:35
【问题描述】:

我正在尝试使用 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.

【问题讨论】:

  • 此错误来自服务器。您的脚本正在正确读取响应。
  • 还不如只使用请求库....
  • Here 是一个相关的 SO 问题。

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


【解决方案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'

【讨论】:

  • 只需使用requests 库,您就不会遇到requests 已经解决的许多其他问题。
  • @barny 我同意,但是,OP 专门尝试使用 socket
【解决方案2】:

这里有多个问题:

  1. 除非与代理通信,否则在GET 之后包含http://data.pr4e.org 是不常见的(请参阅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,但这不是强制性的。请注意 HTTP/1.1 makes the Host: header mandatory,即使您将完整 URL 放在 GET 之后。
  3. HTTP/1.0 使用\r\n ("CRLF") 作为换行符(参见RFC 1945),所以\n 可能并不总是被理解。同样,一些服务器会正​​确处理它,但它是不合格的。 CRLF的使用已经carried over to HTTP/1.1
  4. print(data.decode()) 将在 data 的末尾添加一个额外的换行符。如果 TCP 对较大的 HTTP 响应进行分段以便 recv() 返回多个非空字符串,这可能会成为一个问题。请改用print(data.decode(), end='')

【讨论】:

  • 这是对这个问题的完全有效的批评,但这并不能成为答案。
  • @barny:\r\n 问题是导致 OP 在这种情况下出现特定错误的原因,所以我根本不明白这是“不是答案”。
猜你喜欢
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 2016-06-28
  • 2017-09-14
  • 2018-04-27
  • 2016-10-11
  • 1970-01-01
  • 2015-05-01
相关资源
最近更新 更多