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

eye*_*ick 4 python sockets python-requests

我有一个python 3.4脚本获取多个网页.起初,我使用请求库来获取页面:

def get_page_requsets(url):
    r = requests.get(url)
    return r.content
Run Code Online (Sandbox Code Playgroud)

上面的代码给出了每秒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
Run Code Online (Sandbox Code Playgroud)

平均速度降至每秒4.04个请求.我并不希望提高速度,但是希望稍微增加,因为套接字更低.这个图书馆问题还是我做错了什么?

Mar*_*ers 7

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

  • 通过可选的客户端证书验证,为多个请求重用相同的套接字连接.见:HTTPConnectionPoolHTTPSConnectionPool

此外,urllib3requests做广告,他们可以处理服务器压缩响应; 通过压缩,您可以在相同的时间内传输更多数据,从而导致每秒更多的请求.

  • 支持gzip和deflate解码.见:decode_gzip()decode_deflate()

urllib3也使用套接字(尽管通过http.client模块); 重新发明这个轮子没什么意义.也许您应该考虑并行获取URL,使用线程或多处理或eventlet; 在requests笔者有一个gevents,请求集成包,可以帮助那里.