[英]concurrent.futures multithreading with 2 lists as variables
所以我想用并发期货对以下工作代码进行多线程处理,但到目前为止我尝试过的任何东西似乎都不起作用。
def download(song_filename_list, song_link_list):
with requests.Session() as s:
login_request = s.post(login_url, data= payload, headers= headers)
for x in range(len(song_filename_list)):
download_request = s.get(song_link_list[x], headers= download_headers, stream=True)
if download_request.status_code == 200:
print(f"Downloading {x+1} out of {len(song_filename_list)}!\n")
pass
else:
print(f"\nStatus Code: {download_request.status_code}!\n")
sys.exit()
with open (song_filename_list[x], "wb") as file:
file.write(download_request.content)
两个主要变量是song_filename_list
和song_link_list
。
第一个列表包含每个文件的名称,第二个列表包含它们各自的下载链接。
所以每个文件的名称和链接都位于相同的位置。
例如: name_of_file1 = song_filename_list[0]
和link_of_file1 = song_link_list[0]
这是多线程的最新尝试:
def download(song_filename_list, song_link_list):
with requests.Session() as s:
login_request = s.post(login_url, data= payload, headers= headers)
x = []
for i in range(len(song_filename_list)):
x.append(i)
with concurrent.futures.ThreadPoolExecutor() as executor:
executor.submit(get_file, x)
def get_file(x):
download_request = s.get(song_link_list[x], headers= download_headers, stream=True)
if download_request.status_code == 200:
print(f"Downloading {x+1} out of {len(song_filename_list)}!\n")
pass
else:
print(f"\nStatus Code: {download_request.status_code}!\n")
sys.exit()
with open (song_filename_list[x], "wb") as file:
file.write(download_request.content)
有人可以向我解释我做错了什么吗?
因为在get_file
函数调用后什么也没有发生。
它跳过所有代码并退出而没有任何错误,那么我的逻辑哪里错了?
编辑 1:
添加打印后:
print(song_filename_list, song_link_list)
with concurrent.futures.ThreadPoolExecutor() as executor:
print("Before executor.map")
executor.map(get_file, zip(song_filename_list, song_link_list))
print("After executor.map")
print(song_filename_list, song_link_list)
以及开始和结束get_file
及其file.write
。
输出如下:
Succesfully logged in!
["songs names"] ["songs links"] <- These are correct.
Before executor.map
After executor.map
["songs names"] ["songs links"] <- These are correct.
Exiting.
换句话说,值是正确的,但它跳过了executor.map
的get_file
。
编辑2:
以下是使用的值。
song_filename_list = ['100049 Himeringo - Yotsuya-san ni Yoroshiku.osz', '1001507 ZUTOMAYO - Kan Saete Kuyashiiwa.osz']
song_link_list = ['https://osu.ppy.sh/beatmapsets/100049/download', 'https://osu.ppy.sh/beatmapsets/1001507/download']
编辑 3:
经过一些修补后,这似乎有效。
for i in range(len(song_filename_list)):
with concurrent.futures.ThreadPoolExecutor() as executor:
executor.submit(get_file, song_filename_list, song_link_list, i, s)
def get_file(song_filename_list, song_link_list, i, s):
download_request = s.get(song_link_list[i], headers= download_headers, stream=True)
if download_request.status_code == 200:
print("Downloading...")
pass
else:
print(f"\nStatus Code: {download_request.status_code}!\n")
sys.exit()
with open (song_filename_list[i], "wb") as file:
file.write(download_request.content)
在您的download()
函数中,您提交整个数组,而您应该提交每个项目:
def download(song_filename_list, song_link_list):
with requests.Session() as s:
login_request = s.post(login_url, data=payload, headers= headers)
for i in range(len(song_filename_list)):
with concurrent.futures.ThreadPoolExecutor() as executor:
executor.submit(get_file, i)
您可以使用 executor .map()
方法简化此操作:
def download(song_filename_list, song_link_list):
with requests.Session() as session:
session.post(login_url, data=payload, headers=headers)
with concurrent.futures.ThreadPoolExecutor() as executor:
executor.map(get_file, song_filename_list, song_link_list)
get_file
函数在哪里:
def get_file(song_name, song_link):
with requests.Session() as session:
download_request = session.get(song_link, headers=download_headers, stream=True)
if download_request.status_code == 200:
print(f"Downloaded {song_name}")
else:
print(f"\nStatus Code: {download_request.status_code}!\n")
with open(song_name, "wb") as file:
file.write(download_request.content)
这避免了线程之间共享状态,从而避免了潜在的数据竞争。
如果您需要监控下载了多少歌曲,您可以使用tqdm ,它有一个thread_map
迭代器包装器,可以做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.