前几天写了个爬虫,抓了几十万的数据,但是跑了20多个小时,深深感觉单线程的爬虫还是灰常慢,所以觉得还是有必要学学多线程,看了一些文章,慢慢自己也开始有点理解,试了写了一个简单的多线程打开页面的练习,记录一下:
import threading
import datetime,time
import queue
import requests
#定义需要访问的页面url
url='http://www.jdcsww.com/qcgglist?ggxh=&ggpc=%s&zwpp=&clmc=&fdjxh=&qymc=&cph=&sbdm=&viewtype=1'
s=requests.Session()
#定义一个主线程是否退出的条件
exitflag=0
#定义自己需要多线程运行的函数
def spider(q,threadname):
while not exitflag:
lock.acquire()
if not q.empty():
page=q.get()
print('page %s is opening,current thread is %s ,time is %s' % (page, threadname, time.ctime()))
lock.release()
s.get(page)
print('page %s is finished open,current thread is %s ,time is %s'% (page, threadname, time.ctime()))
else:
lock.release()
#生成一个要访问的页面队列,这里访问200个页面
pagequeue=queue.Queue()
for i in range(1,201):
pageurl=url%i
pagequeue.put(pageurl)
#定义一个线程锁
lock=threading.Lock()
#定义一个线程列表,用于存放自己设定的线程
threads=[]
starttime=datetime.datetime.now()
print ('主线程开始,当前时间:%s'%starttime.strftime('%Y-%m-%d %H:%M:%S'))
#自定义线程数量,需要开多少个线程就设置多少
threads_num=1
#生成自定义的线程列表,并开启每个线程
for i in range(1,threads_num+1):
t=threading.Thread(target=spider,args=(pagequeue,'thread'+str(i)),name='thread'+str(i))
threads.append(t)
t.start()
#判断队列是否被清空,若没清空,继续执行线程(若没有这个判断,定义多少个线程就只访问多少个页面)
while not pagequeue.empty():
pass
#改变退出线程的条件,用于spider中判断是否退出
exitflag=1
#堵塞线程,等待所有线程全部结束后退出
for t in threads:
t.join()
endtime=datetime.datetime.now()
print ('主线程结束,当前时间:%s'%endtime.strftime('%Y-%m-%d %H:%M:%S'))
print ('总共%s个线程,花费%s秒'%(threads_num,(endtime-starttime).seconds))
然后分别用1个线程跑和5个线程跑,对比下效果:
1个线程
5个线程
网友评论