Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么套接字实现比请求慢?_Python_Sockets_Python Requests - Fatal编程技术网

Python 为什么套接字实现比请求慢?

Python 为什么套接字实现比请求慢?,python,sockets,python-requests,Python,Sockets,Python Requests,我有一个Python3.4脚本,可以获取多个网页。首先,我使用请求库获取页面: def get_page_requsets(url): r = requests.get(url) return r.content 上述代码给出了每秒4.6个请求的平均速度。 要提高速度,我重写了函数以使用套接字库: def get_page_socket(url): url = urlparse(url) sock = socket.socket(socket.AF_INET,

我有一个Python3.4脚本,可以获取多个网页。首先,我使用请求库获取页面:

def get_page_requsets(url):
    r = requests.get(url)
    return r.content
上述代码给出了每秒4.6个请求的平均速度。 要提高速度,我重写了函数以使用套接字库:

def get_page_socket(url):

    url = urlparse(url)
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((url.netloc, 80))
    req = '''
GET {} HTTP/1.1\r
Host: {}\r
Connection: Keep-Alive\r
\r
    '''.format(url.path, url.host, uagent)
    sock.send(req.encode())
    reply = b''
    while True:
        chunk = sock.recv(65535)
        if chunk:
            reply += chunk
        else:
            break
    sock.close()
    return reply
平均速度下降到每秒4.04个请求。我不希望赛车的速度提高,但希望稍微提高,因为球座的水平较低。
这是库问题还是我做错了什么?

请求使用,它可以非常有效地处理HTTP连接。尽可能重复使用与同一服务器的连接,从而节省套接字连接和拆卸成本:

  • 使用可选的客户端证书验证,对多个请求重新使用相同的套接字连接。请参阅:
    HTTPConnectionPool
    HTTPSConnectionPool
此外,
urllib3
请求
向服务器公布它们可以处理压缩响应;通过压缩,您可以在相同的时间内传输更多的数据,从而每秒产生更多的请求

  • 支持gzip和deflate解码。请参阅:
    decode\u gzip()
    decode\u deflate()

urllib3
也使用套接字(尽管是通过);重新发明这个轮子没有什么意义。也许您应该考虑使用线程、多处理或Eventlet并行获取URL;
请求
作者有一个可以提供帮助的方法。另一种实现并发性的方法是结合使用,因为HTTP请求主要等待网络I/O。

缓慢可能仅仅是因为您的HTTP错误:您发出HTTP/1.1请求,甚至明确指定连接保持活动状态(甚至不需要,因为这是HTTP/1.1隐含的)。但是,您只是从套接字读取数据,并期望服务器在请求完成后关闭连接。但服务器不会这样做,它会等待更多来自您的请求,因为“保持活动”,只有在一段时间不活动后才关闭连接,这取决于服务器配置。幸运的是,您可以在很短的超时时间内连接到一个服务器,在这个服务器上,您仍然每秒收到4.04个请求,而在其他服务器上,您的代码每分钟只收到很少的请求

如果要使用普通套接字发出简单的HTTP请求,请使用HTTP/1.0,不要使用keep-alive。然后,您可以一直读到服务器关闭,并且您也不必处理HTTP/1.1引入的分块传输编码。您也不必处理压缩编码,因为您并没有特别接受它们(但一些坏掉的服务器还是会发送它们)


但是,虽然这将使您的代码比现在更快,但它不会像请求那样快,因为所有这些都是为了提高速度而添加的保持活动、压缩等。要正确地重新实现这一切并不是那么容易,因此我建议您继续使用请求库。

也许请求库的实现与您的实现大致相同,在这种情况下,它们的性能类似也就不足为奇了。每秒4或5个请求时,您不受客户端资源的限制,您显然受到网络或服务器的限制。因此,如果直接使用套接字,则差别不大。事实上,高级库应该更聪明,从而更快。如果是网络延迟,请使用;如果是吞吐量,则使用压缩;如果服务器被限制,请使用并行连接。一个快速的解决方案是使用
curl\u multi
接口,或者请求离实现还很远。:-)