目录
  • socket解析http请求内容
    • 思路
      • 1. 解析http请求的头部
      • 2. 请求头里面含有content-length参数
      • 3. 请求头里面含有transfer-encoding: chunked 参数
    • 代码实现
    • socket 模拟http请求

      socket解析http请求内容

      思路

      1. 解析http请求的头部

      http请求头部的结束符行为”\r\n”,可以按行读取http请求头的内容,如果读到一行为”\r\n”,说明http请求头结束。

      2. 请求头里面含有content-length参数

      如果http请求里面有content-length参数,说明http请求的内容大小是确定的,请求直接读取content-length的值,然后读取相应字节的的内容即可。

      3. 请求头里面含有transfer-encoding: chunked 参数

      如果http请求里面有transfer-encoding参数,说明http请求的内容大小是不确定的,这种内容的结束符是”0\r\n\r\n”,因此可以按行读取http请求的内容部分,如果连续读到”0\r\n”和”\r\n”说明内容读取完毕。

      代码实现

      代码中: self._file 代表的是socket.makefile() 

       def get_http_content(self):
              content_length = 0
              transfer_encoding = false
              while true:
                  req_line = self._file.readline()
                  req_line = str(req_line, "utf-8")
       
                  # 遇到http头结束符
                  # 读取http内容
                  if req_line == "\r\n":
                      if content_length != 0:
                          content = self._file.read(content_length)
                          content = str(content, "utf-8")
                          self._content = content
                          return none
       
                      if transfer_encoding:
                          content = ""
                          self._file.readline()
                          while true:
                              line = self._file.readline()
                              line = str(line, "utf-8")
                              if line == "0\r\n":
                                  sub_line = self._file.readline()
                                  sub_line = str(sub_line, "utf-8")
                                  if sub_line == "\r\n":
                                      self._content = content
                                      return none
                              else:
                                  content += line
                                  continue
                          self._content = false
       
                  # 头文件没有结束
                  # 并且没有找到关于内容大小的字段
                  else:
                      if content_length == 0 and transfer_encoding is false:
                          words = req_line.split()
                          if words[0] == "content-length:":
                              content_length = int(words[1])
                          if words[0] == "transfer-encoding:":
                              transfer_encoding = true
       
                  self._content = false

      socket 模拟http请求

      # coding: utf-8
      import socket
      from urllib.parse import urlparse
      def get_url(url):
          url = urlparse(url)
          host = url.netloc
          path = url.path
          if path == "":
              path = "/"
          # 建立 socket 连接
          client = socket.socket(socket.af_inet, socket.sock_stream)
          client.connect((host, 80))
          client.send("get {} http/1.1\r\nhost:{}\r\nconnection:close\r\n\r\n".format(path, host).encode("utf-8"))
          data = b""
          while true:
              d = client.recv(1024)
              if d:
                  data += d
              else:
                  break
          data = data.decode("utf-8")
          html_data = data.split("\r\n\r\n")[1]
          print(html_data)
          client.close()
          pass
      if __name__ == '__main__':
          get_url("http://www.baidu.com")

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。