我试图用一个 Python 库制作 Instagram scraper。一切顺利,但速度很慢。我试图通过使用多线程来加快速度,但出现了另一个问题。 这是没有多线程的代码,效果很好:
import threading
import instaloader
import time
L = instaloader.Instaloader()
def func1(name):
first = []
posts = instaloader.Profile.from_username(L.context, name).get_posts()
posts = list(posts)
for p in posts[0:5]:
first.append(p)
return first
def func2(name):
second = []
posts = instaloader.Profile.from_username(L.context, name).get_posts()
posts = list(posts)
for p in posts[5:10]:
second.append(p)
return second
t = time.time()
print(func1('eminem'))
print(func2('eminem'))
print(time.time()-t) # this is 47.43 seconds
但是当我尝试使用多线程时,我发现我的代码执行时间要短得多,但我没有得到结果,它不适用于“return”语句。我需要使用 return 语句,因为这只是代码的一部分,所以我不能使用 print。 这是带线程的代码:
L = instaloader.Instaloader()
def func1(name):
first = []
posts = instaloader.Profile.from_username(L.context, name).get_posts()
posts = list(posts)
for p in posts[0:5]:
first.append(p)
return first
def func2(name):
second = []
posts = instaloader.Profile.from_username(L.context, name).get_posts()
posts = list(posts)
for p in posts[5:10]:
second.append(p)
return second
t = time.time()
t1 = threading.Thread(target = func1, args=('eminem',))
t2 = threading.Thread(target = func2, args=('eminem',))
t1.start()
t2.start()
t1.join()
t2.join()
print(time.time()-t) # this is 25.36 seconds
我做错了什么?
请您参考如下方法:
在您的情况下,最简单的方法是传递具有不同键的共享数据结构,以累积来自不同函数的结果:
而不是使用本地列表 first = [] ; second = [] - 将结果附加到共享结构,如:
def func1(name, results):
...
for p in posts[0:5]:
results['func1'].append(p)
func2 函数也是如此。
results = {'func1': [], 'func2': []}
t1 = threading.Thread(target = func1, args=('eminem', results))
t2 = threading.Thread(target = func2, args=('eminem', results))
t1.start()
t2.start()
t1.join()
t2.join()
print(results)
另一个选项是使用 concurrent.futures.Executor.submit方法。
