解决jupyter使用多线程multiprocessing怕不了的报错问题,并使用tqdm显示进度条

最近在工作上需要进行一个爬虫的演示,需要在界面上输入账号,密码,然后开始爬取数据,需要使用多进程爬虫以加快爬取速度,之前一直没用过多进程,Pycharm可以跑,但需要在jupyter上运行(Pycharm使用不了getpass隐藏输入),所以今天写代码时候遇到了不少问题,在此总结一下。

python版本3.7.6
jupyter lab版本1.2.6

①jupyter notebook/lab中直接使用多进程的话,虽然在界面上不会报错,但一直会处于运行状态,去查看命令行的话会看到报错:
AttributeError: Can’t get attribute ‘XXX’ on <module ‘main’ >,由于某些原因Pool不能始终使用未在导入的模块中定义的对象。
②运行时报错:
AttributeError: module ‘main’ has no attribute ‘spec’,这时需要在if name == ‘main’:下面加上:
spec = “ModuleSpec(name=‘builtins’, loader=<class ‘_frozen_importlib.BuiltinImporter’>)”

jupyter只能跟踪主进程,没法跟踪子进程,网上有一些其他的解决办法,但个人觉得最简单的还是将代码打包成py文件,再让jupyter执行这个文件,代码如下:

因为爬虫需要输入账号,密码获取cookie,所以这里为了测试写了个函数输入账号,然后传入worker和main函数中,看是否能正常运行

%%writefile  test.py
import os,time
from multiprocessing import Pool
from tqdm import tqdm
import getpass
import time
def user_info():
    user = input('请输入用户名:')
    psw = getpass.getpass('请输入密码:')#隐藏密码
    return user,psw
    
def worker(x,user,psw):
    return x*x
    
def main(user,psw):
    lst = []
    print("主进程开始执行>>> pid={}".format(os.getpid()))
    ps=Pool(processes=12)
    with tqdm(total=len(range(500))) as t:
        for i in range(500):
            res = ps.apply_async(worker,args=(i,user,psw)) # 异步执行,args为传入的参数
            print(res.get())#输出worker计算的结果
            #print(i)
            t.update()
            time.sleep(0.1)
        # 关闭进程池,停止接受其它
        ps.close()
        # 阻塞进程
        ps.join()
        print("主进程终止")
if __name__ == '__main__':
    user,psw = user_info()
    print(user)
    __spec__ = "ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>)"#
    main(user,psw)

执行上面代码会在默认路径下生成一个.py文件
在这里插入图片描述
然后再run一:下

%run test.py

在这里插入图片描述
大功告成!

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Python中,可以使用`multiprocessing`模块来实现多进程编程。而要在多进程中同时使用`tqdm`来显示进度条,可以采用以下步骤: 首先,导入所需的模块和函数: ```python from multiprocessing import Pool from tqdm import tqdm ``` 然后,定义一个要在多进程中执行的函数,例如`run_task`: ```python def run_task(arg): # 这里是要执行的任务代码,可以根据实际情况进行修改 return arg * arg ``` 接着,定义一个函数来初始化进程池,并使用`tqdm`来显示进度条: ```python def main(): # 定义进程池大小 pool_size = 5 # 定义要处理的任务数量 task_count = 10 # 初始化进程池 pool = Pool(pool_size) # 使用tqdm显示进度条 with tqdm(total=task_count) as pbar: # 使用imap函数在多个进程中执行任务 for result in pool.imap(run_task, range(task_count)): # 这里可以对result进行处理或输出 pbar.update(1) # 关闭进程池 pool.close() pool.join() ``` 最后,调用`main`函数来执行多进程编程并显示进度条: ```python if __name__ == '__main__': main() ``` 以上代码将使用`tqdm`库来显示进度条,同时使用`multiprocessing`模块实现多进程编程。其中,`pool_size`用于定义进程池的大小,`task_count`表示要处理的任务数量。在`for`循环中,通过`imap`函数在多个进程中执行任务,并在每次任务完成后更新进度条。 总结起来,使用Python的`multiprocessing`模块和`tqdm`库可以实现同时进行多个进程的任务并在处理过程中显示进度条
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值