Python:从HTTP服务器下载文件

时间:2011-01-31 20:36:57

标签: python http

我已经编写了一些python脚本来从HTTP网站上下载图像,但是因为我正在使用urllib2,它会关闭现有连接,然后在打开另一个连接之前打开另一个连接。我真的不太了解网络,但这可能会大大降低速度,一次抓取100张图像需要相当长的时间。

我开始关注其他替代方案,比如pycurl或httplib,但发现与urllib2相比,它们很复杂,并且没有找到我可以采用和使用的大量代码片段。

简单地说,如何建立与网站的持久连接并下载大量文件,然后仅在我完成后关闭连接? (可能是明确要求关闭它)

3 个答案:

答案 0 :(得分: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请求,然后关闭连接。

答案 1 :(得分:1)

我找到urllib3并声称重用现有的TCP连接。

正如我在对该问题的评论中已经说过的那样,我不同意该声明,这不会产生很大的不同:因为auf TCP Slow Start算法每次新创建的连接起初都会很慢。因此,如果数据很大,重复使用相同的TCP套接字会有所不同。我认为100的数据将在10到100 MB之间。

以下是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 :(得分: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会话通常不会产生大量开销。