如何优化此for-with循环?

时间:2018-09-17 15:07:04

标签: python performance loops python-requests fwrite

我写了一个脚本,可以从Wikipedia下载PDF文件。 我实现了一个循环,以遍历要下载的所有URL(我将它们保存在.csv文件中)。前几个文件的下载速度非常快(难怪它们的大小只有200kB),但是过了一会儿,下载的时间越来越长。 感觉好像我的循环呈指数增长,这使我的循环在每次迭代后变慢。 也许我没有以正确的方式关闭请求,我真的不知道。

有人可以帮助我使这段代码更糟,更有效吗? urlstitles都是列表。它们是通过相同的函数传递的,所以我可以将它们转换成字典。

    def getPDF(urls, titles, path):
    i = 0
    for i in range(len(urls) - 1):
        i += 1
        with open(path + '/{}.pdf'.format(titles[i]), 'wb') as f:
            with requests.session() as s:
                r = s.get(urls[i])
                f.write(r.content)
        print('{}.pdf'.format(titles[i]) + ' downloaded!')

编辑: 它必须与请求有关。我添加了一个打印输出时间的函数(从getPDF()的第一行到print()的行。结果如下:

Downloads werden gestartet, das Programm beendet automatisch...

Wirtschaft.pdf downloaded! (2.606057643890381sec)
Wirtschaftseinheit.pdf downloaded! (1.41001296043396sec)
Planung.pdf downloaded! (1.6632893085479736sec)
Bedürfnis#In den Wirtschaftswissenschaften.pdf downloaded! (1.4947214126586914sec)
Unternehmen.pdf downloaded! (2.317748546600342sec)
Privathaushalt.pdf downloaded! (122.32739114761353sec)
%C3%96ffentlicher Haushalt.pdf downloaded! (2.03417706489563sec)
Absatzwirtschaft.pdf downloaded! (0.8923726081848145sec)
Produktion.pdf downloaded! (0.2800614833831787sec)
Tausch.pdf downloaded! (1.5359272956848145sec)
Konsum.pdf downloaded! (121.9487988948822sec)
Entsorgungswirtschaft.pdf downloaded! (121.20771074295044sec)
Gut (Wirtschaftswissenschaft).pdf downloaded! (245.15847492218018sec)

Fertig!

注意:我将此代码放入代码中,以便对其进行格式化,我希望那没事。

很明显,您在4个请求后会收到类似“罢工”的信息,然后需要等待2分钟,最后您立即中风,甚至不得不等待4分钟才能收到下一个请求。 这意味着该问题与“下载大文件”无关,而与“如何下载许多非常小的文件?”有关。

我想现在的问题应该是:有人知道您需要添加多少延迟才能解决此问题吗? 您是否同意我的观点,“滞后”一定是由于在很短的时间内发送太多请求而引起的?

1 个答案:

答案 0 :(得分:0)

如果遇到较大的pdf文件,则注释中的建议会很好。如果您使用scrapy

异步下载,即使文件较小也可以获得更快的结果

对于代码美学,您可以将每个单独的职责赋予一个单独的函数,例如:

def fetch(url):
    with requests.session() as s:
        r = s.get(url)
        return (r.content)

您的主要工作者功能可以是:

def save_pdf(url, title, directory):
    filename = make_path(title, directory)
    with open(filename, 'wb') as f:
        content = fetch(url) 
        f.write(content)

和主循环控制循环:

for t in targets:
   savePDF(t['url'], t['title'], directory)

希望有帮助。