Python 多处理不保存数据
我的程序基本上是从我制作的网站上截取图像。我有3个函数,每个函数都使用一个参数从特定网站上刮取图像。我的程序包含以下代码Python 多处理不保存数据,python,python-3.x,beautifulsoup,multiprocessing,Python,Python 3.x,Beautifulsoup,Multiprocessing,我的程序基本上是从我制作的网站上截取图像。我有3个函数,每个函数都使用一个参数从特定网站上刮取图像。我的程序包含以下代码 import requests from bs4 import BeautifulSoup from multiprocessing import Process img1 = [] img2 = [] img3 = [] def my_func1(img_search): del img1[:] url1 = "http://www.somewebsi
import requests
from bs4 import BeautifulSoup
from multiprocessing import Process
img1 = []
img2 = []
img3 = []
def my_func1(img_search):
del img1[:]
url1 = "http://www.somewebsite.com/" + str(img_search)
r1 = requests.get(url1)
soup1 = BeautifulSoup(r1.content)
data1 = soup1.find_all("div",{"class":"img"})
for item in data1:
try:
img1.append(item.contents[0].find('img')['src'])
except:
img1.append("img Unknown")
return
def my_func2(img_search):
del img2[:]
url2 = "http://www.somewebsite2.com/" + str(img_search)
r2 = requests.get(url2)
soup2 = BeautifulSoup(r2.content)
data2 = soup2.find_all("div",{"class":"img"})
for item in data2:
try:
img2.append(item.contents[0].find('img')['src'])
except:
img2.append("img Unknown")
return
def my_func3(img_search):
del img3[:]
url3 = "http://www.somewebsite3.com/" + str(img_search)
r3 = requests.get(url3)
soup3 = BeautifulSoup(r3.content)
data3 = soup3.find_all("div",{"class":"img"})
for item in data3:
try:
img3.append(item.contents[0].find('img')['src'])
except:
img3.append("img Unknown")
return
my_func1("orange cat")
my_func2("blue cat")
my_func3("green cat")
print(*img1, sep='\n')
print(*img2, sep='\n')
print(*img3, sep='\n')
刮片工作得很好,但是速度很慢,所以我决定使用多处理来加速它,事实上多处理确实加速了它。我基本上用这个替换了函数调用
p = Process(target=my_func1, args=("orange cat",))
p.start()
p2 = Process(target=my_func2, args=("blue cat",))
p2.start()
p3 = Process(target=my_func3, args=("green cat",))
p3.start()
p.join()
p2.join()
p3.join()
但是,当我打印img1、img2和img3列表时,它们是空的。如何解决此问题?当您使用
多处理
在多个进程之间分配工作时,每个进程将在单独的命名空间(主进程命名空间的副本)中运行。您在子进程的命名空间中所做的更改不会反映在父进程的命名空间中。您需要使用多处理.Queue
或其他同步方法将数据从工作进程传回
在示例代码中,这三个函数几乎完全相同,只是网站的域和变量名不同。如果实际函数是这样的,我建议使用multiprocessing.Pool.map
并将整个URL传递给单个函数,而不仅仅是传递搜索词:
def my_func(search_url):
r = requests.get(search_url)
soup = BeautifulSoup(r.content)
data = soup.find_all("div",{"class":"img"})
images = []
for item in data:
try:
images.append(item.contents[0].find('img')['src'])
except:
images.append("img Unknown")
return images
if __name__ == "__main__":
searches = ['http://www.somewebsite1.com/?orange+cat', # or whatever
'http://www.somewebsite2.com/?blue+cat',
'http://www.somewebsite3.com/?green+cat']
pool = multiprocessing.Pool() # will create as many processes as you have CPU cores
results = pool.map(my_func, searches)
pool.close()
# do something with results, which will be a list with of the function return values
在我的例子中,如何使用队列将数据传递到列表中?事实上,现在我看一下您的辅助函数,我发现它们几乎是相同的。如果这不是堆栈溢出的简化,我建议用单个函数替换它们,并使用
multiprocessing.Pool.map
。池负责启动流程并为您设置队列。即使您确实需要单独的辅助函数,也可以在池上使用apply_async
,我目前正在使用此文档:获取帮助。如果你能,请你演示一个简单的例子来指导我,我将不胜感激。谢谢。我已经编辑了我的答案,使用多处理.Pool
@SagwaTheCat添加了一些(未经测试的)示例代码:您可以使用多处理.dummy.Pool
,它使用线程而不是进程。看看在你的情况下什么效果最好。