【问题标题】:python socket GETpython 套接字 GET
【发布时间】:2016-03-15 12:14:42
【问题描述】:

从堆栈溢出的其他帖子来看,这应该可以工作

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                 

s.connect(("www.cnn.com" , 80))
s.sendall("GET / HTTP/1.1\r\n")
print s.recv(4096)
s.close

但由于某种原因,它只是挂起(recv)并且从不打印。我知道对 www.cnn.com 的请求会对其数据进行分块,但我至少应该从recv 中读取一些内容,对吧?

附言我知道这不是最好的方法,并且有像 httpliburllib2 这样的图书馆,但我不能在这个项目中使用它们(它是给学校的)。我必须使用socket

【问题讨论】:

    标签: python python-sockets


    【解决方案1】:

    您忘记在请求行之后发送一个空行:

    s.sendall("GET / HTTP/1.1\r\n\r\n")
    

    此外,HTTP 1.1 指定您应该添加 Host 标头字段,如 Host section in the HTTP 1.1 RFC 中所述。

    s.sendall("GET / HTTP/1.1\r\nHost: www.cnn.com\r\n\r\n")
    

    【讨论】:

      【解决方案2】:

      您的代码几乎是正确的,但您需要发送 2 个\r\n 序列以满足 HTTP 协议。

      一个有效的 GET 请求将如下所示(注意 2 行):

      获取/HTTP/1.1

      所以你的代码应该是:

      s.sendall('GET / HTTP/1.1\r\n\r\n')
      

      此外,有效的 HTTP 1.1 请求还需要额外的标头,例如 Host:。您需要将它们添加到您的请求中,如下所示:

      s.sendall('''GET / HTTP/1.1
      Host: cnn.com
      
      ''')
      

      【讨论】:

      • 这确实回答了我的问题,而且是第一个,所以我想我会纠正的。对于其他人,也请参阅我自己的答案
      • @jamessmith:您应该选择最佳答案,而不是第一个答案。无论如何,我认为 Takis 先回答了 :)
      【解决方案3】:

      抱歉浪费了大家的时间。我刚刚在 Stack Overflow 上找到了这个解决方案 here(只是在我的 Google 搜索中进行了一些改写)

      import socket
      request = b"GET / HTTP/1.1\nHost: www.cnn.com\n\n"
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      s.connect(("cnn.com", 80))
      s.send(request)
      result = s.recv(10000)
      while (len(result) > 0):
          print(result)
          result = s.recv(10000)
      

      所有关于结尾\r\n\r\n 的答案都是正确的,但是那些返回301 状态。该解决方案似乎以某种方式遵循重定向?无论如何,这个解决方案对我有用

      【讨论】:

      • 该代码给出 302 响应。它不遵循重定向。你需要为你的学校项目处理重定向吗?
      【解决方案4】:

      我正在清理 Python 3 的示例。我们需要字节/字符串转换,我们还可以使用 with 自动关闭连接:

      #!/usr/bin/env python3
      
      import socket
      
      with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
      
          s.connect(("example.com" , 80))
          s.sendall(b"GET / HTTP/1.1\r\nHost: example.com\r\nAccept: text/html\r\n\r\n")
          print(str(s.recv(4096), 'utf-8'))
      

      【讨论】:

        【解决方案5】:

        @james:你在不知不觉中进行了 SlowLoris 攻击。我无法比这里更好地解释,https://www.youtube.com/watch?v=XiFkyR35v2Y 我假设您从上述所有答案中找到了解决方案,但我只是回答让您了解这一点。 :)

        【讨论】:

          【解决方案6】:

          尝试替换这一行:

          s.sendall("GET / HTTP/1.1\r\n")
          

          与:

          s.sendall("GET / HTTP/1.1\r\n\r\n")
                                       ^^^^
          

          另外,我认为您需要将 s.close 替换为 s.close(),因为它是一个函数。

          【讨论】:

            猜你喜欢
            • 2015-02-05
            • 2020-11-16
            • 1970-01-01
            • 1970-01-01
            • 2020-04-01
            • 1970-01-01
            • 2010-11-06
            • 2020-12-09
            相关资源
            最近更新 更多