Python:从HTTP服务器下载文件

0 投票
3 回答
4711 浏览
提问于 2025-04-16 10:57

我写了一些Python脚本,用来从一个HTTP网站下载图片。但是因为我用的是urllib2,这个库会关闭已经建立的连接,然后再打开一个新的连接。虽然我对网络知识了解不多,但我觉得这样会让速度变得很慢,一次下载100张图片可能需要花费很长时间。

我开始寻找其他的替代方案,比如pycurl或httplib,但发现这些比urllib2复杂得多,而且我也没找到很多可以直接拿来用的代码示例。

简单来说,我该怎么才能和一个网站建立一个持续的连接,下载一些文件,然后在完成后再关闭这个连接呢?(可能需要明确地调用关闭连接的命令)

3 个回答

0

如果你不打算发起什么复杂的请求,你可以自己打开一个socket,然后像这样发请求:

import sockets

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((server_name, server_port))

for url in urls:
    sock.write('get %s\r\nhost: %s\r\n\r\n' % (url, server_name))
    # Parse HTTP header
    # Download picture (Size should be in the HTTP header)

sock.close()

不过我觉得建立100个TCP连接一般来说不会造成太大的负担。

1

我发现了一个叫做 urllib3 的库,它声称可以重用已有的TCP连接。

正如我在对这个问题的评论中提到的,我不同意这种说法,即这不会有太大区别。因为TCP的 慢启动 算法,每次新建立的连接开始时都会比较慢。所以如果能重用同一个TCP连接的话,对于大数据量的传输来说,确实会有区别。我认为对于100的数据量来说,数据大小会在10到100MB之间。

这里有一个来自 http://code.google.com/p/urllib3/source/browse/test/benchmark.py 的代码示例。

TO_DOWNLOAD = [
'http://code.google.com/apis/apps/',
'http://code.google.com/apis/base/',
'http://code.google.com/apis/blogger/',
'http://code.google.com/apis/calendar/',
'http://code.google.com/apis/codesearch/',
'http://code.google.com/apis/contact/',
'http://code.google.com/apis/books/',
'http://code.google.com/apis/documents/',
'http://code.google.com/apis/finance/',
'http://code.google.com/apis/health/',
'http://code.google.com/apis/notebook/',
'http://code.google.com/apis/picasaweb/',
'http://code.google.com/apis/spreadsheets/',
'http://code.google.com/apis/webmastertools/',
'http://code.google.com/apis/youtube/',
]

from urllib3 import HTTPConnectionPool
import urllib

pool = HTTPConnectionPool.from_url(url_list[0])
for url in url_list:
    r = pool.get_url(url)
2

因为你问了一个关于httplib的代码片段:

import httplib

images = ['img1.png', 'img2.png', 'img3.png']

conn = httplib.HTTPConnection('www.example.com')

for image in images:
    conn.request('GET', '/images/%s' % image)
    resp = conn.getresponse()
    data = resp.read()
    with open(image, 'wb') as f:
        f.write(data)

conn.close()

这段代码会依次发送多个GET请求来获取列表中的图片,然后关闭连接。

撰写回答