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

前言:这几天忙活的做个网页玩玩,网上也没有教程。买个域名又得解析,又得备案,真是麻烦,觉得一个简单的HTML网页应该用不到那么麻烦吧。
昨天又看了几个关于多线程爬虫的例子,觉得很好,提炼出来,总结几个应用模板。

目录

一 多线程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爬虫(四)–多线程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值