python 多线程下载图片示例

本文介绍了如何使用Python的pymysql和requests库进行数据库查询,利用concurrent.futures模块实现多线程下载图片,优化了图片下载速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import os
import time
import pymysql
import requests
import threading
from concurrent.futures import ThreadPoolExecutor, as_completed

def db(sql):
    conn = pymysql.connect(host="xxx", port=3306, user='xxx', password=xxxx
                           database='xx')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql)
    result = cursor.fetchall()  # [{},{}]
    car_len = len(result)
    cursor.close()
    conn.close()
    return result, car_len


def car_inout_sql():
    # 偏移基准日间
    sql = f"""SELECT id,base_photo2 FROM building_door WHERE deleted=0 AND area_id=19;"""
    return sql


count = 1
count_lock = threading.Lock()

def download(url, id):
    global count
    my_header = "https://xxxx/minio/"
    path = "./偏移告警基准/"
    # print(path)
    # count_lock.acquire()
    try:
        # r = requests.get(my_header + url, timeout=10)

        # 偏移
        if not url.startswith("http"): # 有前缀
            r = requests.get(my_header + url, timeout=10)
        else:
            r = requests.get(url, timeout=10)
        if r.status_code != 404:
            count_lock.acquire() # 加锁
            with open(path + str(id) + "_" + str(count) + ".jpg", 'wb') as f:
                f.write(r.content)

                count += 1
                count_lock.release() # 释放
                print(f""" {count}/{my_car_len}""")

    except Exception as e:
        print(e)
        count_lock.acquire()
        count += 1
        count_lock.release()


if __name__ == '__main__':
    st = time.time()
    my_sql = car_inout_sql()
    my_result, my_car_len = db(my_sql)  # [a,b,c] [{},{}]

    # 创建多个线程 方式一 线程数没有上限
    # threads = []
    #
    # for i in my_result:
    #     thread = threading.Thread(target=download, args=(i["photo"], i["id"]))
    #     threads.append(thread)
    #
    # # 开启所有线程
    # for thread in threads:
    #     thread.start()
    #
    # # 等待所有线程完成
    # for thread in threads:
    #     thread.join()
    # et=time.time()
    # print(et-st)
    
    # 创建多个线程 方式 二 固定线程数
    with ThreadPoolExecutor(max_workers=200) as executor:
        # 提交下载任务
        # futures = [executor.submit(download, i["photo"], i["id"]) for i in my_result]
        futures = [executor.submit(download, i["base_photo2"], i["id"]) for i in my_result]
        # 等待任务完成
        for future in as_completed(futures):
            pass
    et = time.time()
    print(et - st)
  • 注意:
    count计数器需要被锁住,不然会造成count值重复,加锁的位置可能有待商榷;i["base_photo2"]是图片的url(可能会没有图片前缀),
    下载6400张图片时间从2000多秒提升700多秒
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值