您的位置:首页 > 编程语言 > Python开发

【Python3.6爬虫学习记录】(十四)多线程爬虫模板总结

2017-08-23 10:01 871 查看
前言:这几天忙活的做个网页玩玩,网上也没有教程。买个域名又得解析,又得备案,真是麻烦,觉得一个简单的HTML网页应该用不到那么麻烦吧。

昨天又看了几个关于多线程爬虫的例子,觉得很好,提炼出来,总结几个应用模板。

目录

目录

一 多线程Threading模块
1-1 简单的函数创建多线程

2-1 用类包装线程对象

二 多线程Queue模块
2-1 使用Queue 与 Threading模块

三 多进程并发模块
3-1 Queue 与 Threading实现并发

3-2 multiprocessing模块实现并发

一 多线程Threading模块

1-1 简单的函数创建多线程

## 简单应用thread模块
import socket
import threading
import requests

tasks = []
lock = threading.Lock()  # 建立一个锁

# 线程工作函数
def worker(i):
socket.setdefaulttimeout(5)  # 设置全局超时时间

try:
r = requests.get(url)
lock.acquire()  # 获得锁
print('Processing ',i)
lock.release()  # 释放锁

except Exception as e:
lock.acquire()
print(e)
lock.release()

# 多线程
threads = []
for i in range(len(tasks)):
# 参数包括,目标函数,以及操作对象序号
thread = threading.Thread(target=worker, args=[i])
# 将全部IP加入线程,并开始多线程
threads.append(thread)
thread.start()

# 阻塞主进程,等待所有子线程结束
# 通俗的将,就是执行完上述的过程再结束
for thread in threads:
thread.join()


2-1 用类包装线程对象

import threading
import time

class myThread(threading.Thread):
'''
构造方法
'''
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter

def run(self):
print("Starting " + self.name)
'''打开网页以及查找等操作
'''
# 获得锁,成功获得锁定后返回True
# 可选的timeout参数不填时将一直阻塞直到获得锁定
# 否则超时后将返回False
threadLock.acquire()

'''保存文件,打印操作
'''

print(self.name, self.counter, 3)

# 释放锁
threadLock.release()

threadLock = threading.Lock()
threads = []

'''创建,开始,添加线程组
'''
for i in range(1,3):
# 创建新线程
thread = myThread(i, "Thread-%s"%i, i)
# 开启新线程
thread.start()
# 添加线程到线程列表
threads.append(thread)

# 等待所有线程完成
for t in threads:
t.join()

print("iting Main Thread")


二 多线程Queue模块

2-1 使用Queue 与 Threading模块

import os
import random
import threading
import time
from queue import Queue
import requests

class myThread(threading.Thread):
def __init__(self,func):
# 调用父类构造函数
super(myThread, self).__init__()
# 传入线程函数逻辑
self.func=func
def run(self):
'''
重写run方法
'''
self.func()

# 功能函数
def worker():
global Q
while not Q.empty():
# 获得任务
item = Q.get()
'''
执行的任务
'''
# 原来写Queue,没有初始化
Q.task_done()

'''其他功能性函数
'''

# 主函数
def main():
global Q
threads = []
# 向队列中放入任务
for task in range(len(tasks)):
Q.put(tasks[task])
# 执行线程
for i in range(thread_num):
thread = myThread(worker)
thread.start()
threads.append(thread)
# 等待线程结束
for thread in threads :
thread.join()
# 等待所有线程结束
Q.join()
# 本项目中执行
if __name__ == '__main__':
# 无限制队列
Q = Queue()
# 线程数
thread_num = 100
# 任务对象列表
tasks = []
start = time.time()
main()
end = time.time()
print('It takes ',end-start)


三 多进程并发模块

3-1 Queue 与 Threading实现并发

# 多线程并发模板
from queue import Queue
from threading import Thread
from time import sleep
#q是任务队列
#NUM是并发线程总数
#JOBS是有多少任务
q = Queue()
NUM = 2
JOBS = 10

#具体的处理函数,负责处理单个任务
def do_somthing_using(arguments):
print(arguments)

#这个是工作进程,负责不断从队列取数据并处理
def working():
while True:
arguments = q.get()
do_somthing_using(arguments)
sleep(1)
q.task_done()

#fork NUM个线程等待队列
for i in range(NUM):
t = Thread(target=working)
t.setDaemon(True)
t.start()

#把JOBS排入队列
for i in range(JOBS):
q.put(i)

#等待所有JOBS完成
q.join()


3-2 multiprocessing模块实现并发

from multiprocessing import Pool
pool = Pool(8)
data_list = pool.map(get, url_list)
pool.close()
pool.join()


后记:

有些并不是很理解,但是可以直接套模板。简单简单点来,可以用类包装Threading模块,但是如果应用对象很多,这样一下子把所有的线程都开了,会卡死,应该有解决办法吧,目前还没查到;然后,如果任务对象很多,就直接用queue模块,只开启一定的线程,依次执行,目前应用的蛮好,再看;最后,关于多进程并发的还不是很清楚,之后在了解吧。期间还看到了协程,等知识不够用了再学。

参考链接:

Python爬虫进阶五之多线程的用法

Python爬虫(五)–多线程续(Queue)

Python爬虫实例2-多线程爬虫抓取糗事百科数据

Python爬虫(四)–多线程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 多线程 爬虫
相关文章推荐