关于使用threadpool时的巨坑:报错result = request.callable(*request.args, **request.kwds)

本来想写一个按广度优先爬取所有qq的一些信息和说说,计划线程池来实现多线程

思路:待爬取队列出对200个qq,待爬取队列的组成元素是元组, 即(qq1, depth)

局部代码如下

        #开始出队20线程爬数据,这里不使用threading的原因是每次出队20个线程执行都要join,20个线程中只要还剩一个没执行完,在其他的都要
        #等,效率太慢
        while waiting_get.qsize() >= 200:
            #一次性出队200个,然后放入线程池
            wating_qq_list = []
            for i in range(200):
                wating_qq_list.append(waiting_get.get())
            print(wating_qq_list)
            pool_size = 20
            pool = threadpool.ThreadPool(pool_size)
            # 创建工作请求
            reqs = threadpool.makeRequests(self.get_data, wating_qq_list)
            # 将工作请求放入队列
            [pool.putRequest(req) for req in reqs]
            pool.wait()

这是就会报错:

result = request.callable(*request.args, **request.kwds)
TypeError: get_data() argument after ** must be a mapping, not int

然后研究了下threadpool的源码,

    for item in args_list:
        if isinstance(item, tuple):
            requests.append(
                WorkRequest(callable_, item[0], item[1], callback=callback,
                    exc_callback=exc_callback)
            )
        else:
            requests.append(
                WorkRequest(callable_, [item], None, callback=callback,
                    exc_callback=exc_callback)
            )
    return requests

发现threadPool包会对传入数据进行验证,如果传入的是个元组数据,那么他会把元组数据分开,做另外处理,元组中第一个元素为请求值,即给请求函数调用的值,第二个元素是结果值,就是请求函数执行后的输出值。

如果第二个元素是其它值,则会报错

那么把元组类型改成list就行啦

踩的巨坑,官方手册都没有说明,拿本小本本记下来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值