当前位置:   article > 正文

python爬虫多线程之queue_python. 用queue写爬虫

python. 用queue写爬虫

        首先先来介绍下queue这个包吧,这个包叫队列,没错,就是那个和栈反过来的那个队列,大家一听队列就随口说出先进先出,而栈则是后进先出,为什么要用用队列来实现,其实我也不知道,反正用过之后很顺手,具体哪里也说不上来

        先来看下队列的内置方法的,我们只需要记住两个,一个是put 放 ,另一个是get 获得,因为我们q = queue.Queue()创建了一个队列后,这个队列是空的,要先放东西进去才能从里面拿东西出来

q = queue.Queue()    
q.qsize()           返回队列的大小  
q.empty()         如果队列为空,返回True,反之False  
q.full()          如果队列满了,返回True,反之False 
q.full              与 maxsize 大小对应  
q.get([block[, timeout]]) 获取队列,timeout等待时间  
q.get_nowait()         相当q.get(False) 
q.put(item)           写入队列,timeout等待时间  
q.put_nowait(item)    相当q.put(item, False) 
q.task_done()         在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号 
q.join()             实际上意味着等到队列为空,再执行别的操作

下面是我自己写的一个简单的代码,我会用文字来注释,以便大家能看懂,真心简单,熟悉读完这篇文章后你如果还不会的话,那我也没什么说的了

  1. #开启多个线程,同时执行任务,有几个线程就执行几个任务
  2. import threading
  3. import time
  4. import queue
  5. class MyThread(threading.Thread):
  6. def __init__(self, func):
  7. threading.Thread.__init__(self)
  8. self.func = func
  9. def run(self):
  10. self.func()
  11. def worker():
  12. while not q.empty():
  13. item = q.get() # 或得任务
  14. print('Processing : ',item)
  15. time.sleep(1)
  16. def main():
  17. threads = []
  18. for task in range(100):
  19. q.put(task)
  20. for i in range(threadNum): #开启三个线程
  21. thread = MyThread(worker)
  22. thread.start()
  23. threads.append(thread)
  24. for thread in threads:
  25. thread.join()
  26. if __name__ == '__main__':
  27. q = queue.Queue()
  28. threadNum = 3
  29. main()

看代码先看主入口,根据里面的函数调用一步步来

1.    首先我实例化了一个队列  q = queue.Queue()    ,然后我设置线程数为3,接着调用main() 方法

2.    进入main函数中,我创建了一个空列表,用来放线程,第一个for 循环中我做的是将(0,100)之间数据放入队列当中,当然,100是取不到的,放完队列后又来了个for循环,这个for循环是用来创建线程的,前面说了threadNum = 3,那么说明我这里要循环三次,threadNum的值分别为0,1,2,当然,这三个数用不到,因为我没在MyThread写线程名,没有把thread作为参数传入类中,所以每个线程都是无名氏,我们看到thread = MyThread(worker) 这段代码,先来看MyThread这个类,worker这个参数先不看,MyThread中这个类继承了threading.Thread,在init方法中初始化了父类,也就是threading.Thread,并且定义了一个属性,属性名叫func,因为threading这个类有自己的run方法,我们可以重写父类的run方法,self.func()  表明但我们start后,线程会自动调用run方法,就会执行self.func() 这句

3.     看完MyThread这个类后我们就来看worker这个参数,有的人就会问,看了半天没看到有这个参数啊,谁说参数一定是变量啊,也有可能是函数啊,现在就有人恍然大悟了,看到worker这个方法。这个方法里面一个while循环,我使用的一个队列的方法,这个方法是q.empty(),这个方法说明当队列q为空时,他的值为True,前面写了个not ,说明整句的意思是,当队列q不为空时才会执行这个while循环。一开始定义一个变量item 来接收得到的数据,打印一遍并且休眠一秒,不休眠的话程序运行太快,看不到多线程的效果,以上  thread = MyThread(worker)  这句代码就解释完了

4.     thread.start() 这句是启动线程,threads.append(thread)是将线程加入到前面定义的threads空列表中,最后这个for循环是将每个线程都join()一下,join的意思是等线程结束后才会执行后面的语句,我们这里的意思是前面三个线程跑完了才能轮到后面三个线程

5.    基本的代码都讲解完毕了,现在来运行代码

就会发现,一次输出三句,停顿一秒后又输出三句,因为开了三个线程,有兴趣的可以把我代码复制下来并且将线程数改下来看下效果,看到这估计有人就明白了,这个queue队列相当于或类似一个全局的列表,只负责存和取,没错,他的作用就是这样,最起码我用的只有这么多

下面还有一个列子,这个列子是我想执行一个永不停止的线程,每次队列被取完后,我都会将数据原样放回去,具体的步骤我就不说了,上面有写

  1. import threading
  2. import queue
  3. import time
  4. class Mythread(threading.Thread):
  5. def __init__(self,fun):
  6. threading.Thread.__init__(self)
  7. self.fun = fun
  8. def run(self):
  9. self.fun()
  10. def worker():
  11. global data
  12. while True:
  13. if not q.empty():
  14. a = q.get()
  15. parse(a[0], a[1])
  16. time.sleep(1)
  17. data.append(a)
  18. else:
  19. for i in data:
  20. q.put(i)
  21. data = []
  22. def parse(qd, zd):
  23. mystr = qd + zd
  24. print('=============',mystr)
  25. def main():
  26. threads = []
  27. for i in LstAdd:
  28. q.put(i)
  29. for i in range(thendNum):
  30. thread = Mythread(worker)
  31. thread.start()
  32. threads.append(thread)
  33. for thread in threads:
  34. thread.join()
  35. if __name__ == '__main__':
  36. LstAdd = [
  37. ('abcde1','adfa1'),
  38. ('abcde2','adfa2'),
  39. ('abcde3','adfa3'),
  40. ('abcde4','adfa4'),
  41. ('abcde5','adfa5'),
  42. ('abcde6','adfa6'),
  43. ('abcde7','adfa7'),
  44. ('abcde8','adfa8'),
  45. ('abcde9','adfa9'),
  46. ]
  47. data = []
  48. q = queue.Queue()
  49. thendNum = 3
  50. main()

我想将列表中每个元素即元组的两个元素相加并输出,运行程序结果如下:

他会一直输出1-9,后面的没有截图下来,太多了,我将每次get()的数据都存起来,这样防止数据丢失,每次我都会判断队列是否为空,为空的话就将存起来的数据原样存回去,并且情况存这些数据的列表,保证每次都是同样的数据同样的顺序

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/189666
推荐阅读
相关标签
  

闽ICP备14008679号