admin 管理员组文章数量: 1086019
python进程池(子进程)函数没有执行
文章目录
- 1. 问题描述
- 问题排查经过
- 关于此问题的两个可能原因
内容较长
1. 问题描述
某日,写了一段爬虫代码(如下,爬取糗百图片代码示例),发现一个异常的问题,就是执行代码时,代码会以极快的速度执行完成,但是任何东西都没有爬取下来,经过问题排查,确认为下载方法downloadEngin
内没有执行,我特意在for循环向线程池提交任务处添加了print,执行代码后会print所有提交信息,但是方法downloadEngin
里面的print一条没有输出.
from multiprocessing import Pool
from requests import Session
from lxml import etreeclass getData:def __init__(self):self.session = Session()self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3766.400 QQBrowser/10.6.4163.400'}def downloadEngin(self,downloadUrl,fileName):print("开始下载",downloadUrl,fileName)pictureData = self.session.get("http:" + downloadUrl,headers = self.headers).contentwith open(fileName + '.jpg',mode="wb") as w:w.write(pictureData)def getPage(self,url):pageData = self.session.get(url,headers = self.headers).content.decode('utf-8')self.xpath = etree.HTML(pageData)pictureName = self.xpath.xpath('/html/body/div[1]/div/div[2]/div/div[2]/a/img/@src')pool = Pool(10)for i in range(len(pictureName)):print("提交任务:{}".format(i))pool.apply_async(self.downloadEngin,args=(pictureName[i],str(i)))pool.close()pool.join()
if __name__ == '__main__':getData().getPage('/')
上段代码执行效果:
提交任务:0
提交任务:1
提交任务:2
提交任务:3
提交任务:4
.....
提交任务:22
提交任务:23
提交任务:24进程已结束,退出代码为 0
问题排查经过
我反复确认了代码写的没有问题,仔细想了一下可能影响到多线程任务执行的问题,想到了变量.
提交任务时传递了两个参数,如下,此处先是统计了列表长度然后生成对应的数字,然后开始提交任务
pool.apply_async(self.downloadEngin,args=(pictureName[i],str(i)))
传递参数为:列表的实际内容和列表所在的下标索引的数字值,并将数字转换为字符串,作为保存的文件名.
我在for循环上面添加输出了这个列表,列表内容没有问题,随后,我将整段列表复制下来,在for循环的上面位置,重新定义了这个变量的内容
# ['xxx','yyy'] 为之前复制的整段列表内容
pictureName = ['xxx','yyy']
然后重新执行代码,惊疑的发现可以运行了.
此处的问题很明显了,我就使用最笨的方法不断的将上面和这个变量相关的代码注释,手动赋值等操作,终于定位到了有问题的两行代码.
上面只是示例,当时文件内容多很多,xpath声明为全局是因为还有其他方法要用它
self.xpath = etree.HTML(pageData)
pictureName = self.xpath.xpath('/html/body/div[1]/div/div[2]/div/div[2]/a/img/@src')
上面是有问题代码,解决方式是删除self,下面是修改后的代码
xpath = etree.HTML(pageData)
pictureName = xpath.xpath('/html/body/div[1]/div/div[2]/div/div[2]/a/img/@src')
然后重新执行,可以了.
关于此问题的两个可能原因
- 如果也是在for循环提交任务中添加了print,并且可以正常输出,那么多半是传递的变量有问题,可以在源代码基础上先在for循环上面固定变量的值重新运行尝试
- 还有一种情况是多进程函数执行了,也就是上面的
downloadEngin
中的第一行print代码可以正常输出,但是依旧没有将爬取的数据保存下来,也就是除去了第一行代码其他还是类似没有执行,这种情况一般为多进程执行的函数中的代码写的有问题,某种情况下,Python创建的子进程执行错误不会将错误抛出,而是直接结束了子进程,在控制台看不到任何错误输出,只能将子进程函数复制出来一点点执行排查了.
本文标签: python进程池(子进程)函数没有执行
版权声明:本文标题:python进程池(子进程)函数没有执行 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1686561867a10562.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论