如何阅读Python s

2024-05-23 14:31:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图发送一个HTTP请求到一个网站并读取它返回的数据。我尝试过的第一个网站成功运行。它返回大约4个数据包,然后返回一个0包,脚本捕获并终止了该包。

但是,尝试加载http://www.google.com/不是这样工作的。相反,它返回大约10个相同长度的包,最后一个更小的包,然后继续超时。发生这种事正常吗?这一切仅仅取决于主机使用的服务器吗?

如果有人能推荐一种替代socket.recv()读取的方法,考虑到最终的空数据包并不总是发送的,那将是非常感谢的。谢谢。

    try:
        data = s.recv(4096)

        while True:
            more = s.recv(4096)
            print len(more)
            if not more:
                break
            else:
                data += more
    except socket.timeout:
        errMsg = "Connection timed-out while connecting to %s. Request headers were as     follows: %s", (parsedUrl.netloc, rHeader.headerContent)
        self.logger.exception(errMsg)
        raise Exception

Tags: 数据脚本comhttpdata网站morewww
3条回答

可能是Google使用Keep-Alive来保持套接字打开,以便满足进一步的请求。这需要解析头并读取确切的字节数。

根据您使用的HTTP版本,您必须向头部添加Connection: Keep-Alive或不添加。(这可能是最简单的解决方案:只需使用HTTP/1.0而不是1.1。)

如果仍然使用该功能,则必须接收第一个数据块并

  1. 如果内部有一个'\r\nContent-Length: '则进行解析,如果有,则获取该字节与下一个'\r\n'之间的字节,并将它们转换为数字。这是你的尺码。
  2. 看看你的数据中是否有'\r\n\r\n'。如果是的话,那就是你的头的结尾。从这里开始,您必须读取上面提到的确切字节数。

示例:

import socket
s = socket.create_connection(('www.google.com', 80))
s.send("GET / HTTP/1.1\r\n\r\n")
x = s.recv(10000)
poscl = x.lower().find('\r\ncontent-length: ')
poseoh = x.find('\r\n\r\n')
if poscl < poseoh and poscl >= 0 and poseoh >= 0:
    # found CL header
    poseocl = x.find('\r\n',poscl+17)
    cl = int(x[poscl+17:poseocl])
    realdata = x[poseoh+4:]

现在,在cl中有内容长度,在realdata中有有效负载数据(开始)。此请求缺少的字节数为missing = cl - len(realdata)。如果它是0,那么您就得到了所有的东西;如果不是,那么执行s.read(missing),并重新计算missing,直到它是0。

上面的代码是要完成的工作的简单开始;有些地方可能需要recv()更进一步,然后才能继续。

这是相当顺从的。更简单的方法是

  1. 要在请求中使用HTTP 1.1的Connection: close
  2. 要使用HTTP 1.0
  3. 使用为此任务精心设计的库之一,而不是重新发明轮子。

TCP不提供“数据包”,而是从另一端发送的顺序字节这是一条流。recv()提供当前可用的流块。将它们缝合在一起,解析流内容。

HTTP相当复杂,需要手工制定协议,因此您可能希望从一些现有的库(如httplib)开始。

对于HTTP,使用requests而不是自己编写。

> ipython

In [1]: import requests

In [2]: r = requests.get('http://www.google.com')

In [3]: r.status_code
Out[3]: 200

In [4]: r.text[:80]
Out[4]: u'<!doctype html><html itemscope="itemscope" itemtype="http://schema.org/WebPage">'

In [5]: len(r.text)
Out[5]: 10969

相关问题 更多 >