爬虫学习笔记 - 多任务

多线程爬虫

  • threading
    • t1 = threading.Thread(targe=func,args=(,))
    • t1.setDaemon(True)
    • t1.start() #此时线程才会启动
  • 队列
    • q.join() #阻塞主线程,让主线程等待队列任务结束之后在结束,队列任务在计数为0时技术
    • q.task_done() 和get()方法配合,队列计数-1
    • q.put() 队列计数+1

多进程爬虫

  • multiprocessing
    • p = multiprocessing.Process(trage=func,args=(,))
    • p.daemon = True #设置为守护线程
    • p.start()
  • from multiprocessing import JoinableQueue
    • q = JoinableQueue()
    • q.join() #让主进程阻塞,等待队列任务结束,
    • q.put() #计数+1
    • q.get() #计数不会-1
    • q.task_done() #get和task_done一起使用才会减一

线程池爬虫

  • from multiprocessing.dummy import Pool
  • pool.apply_async(func,callback=fun2)
"""
多线程、线程池能够实现并发吗?
由于CPython的GIL(全局解释器锁)的限制,同一时刻只有一个线程被执行,而且不能利用CPU多核的特性
线程执行时,会为当前线程上锁,其他线程等待,遇到以下两种情况会释放锁,去执行其他线程任务
    1. 线程遇到阻塞情况
    2. 调用了 time.sleep()
并不是真的并发执行,只是速度太快,看上去像并发

多线程、线程池 适合 IO密集型的任务
"""

"""
使用线程池的好处:

1. 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
2. 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
3. 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,
使用线程池可以进行统一的分配,调优和监控
"""

多线程

import threading
from queue import Queue

多进程

from multiprocessing import Process
from multiprocessing import JoinableQueue as Queue

线程池

from multiprocessing.dummy import Pool
from queue import Queue

协程池

from gevent import monkey
monkey.patch_all()
from gevent.pool import Pool

进程池

from multiprocessing import Pool
from multiprocessing import Manager
Manager().Queue()


xpath的包含

  • //a[contains(text(),"下一页")]选择文本包含下一页三个字的a标签
  • //a[contains(@class,'n')] class包含n的a标签

url地址解码的方法

requests.utils.unquote(url)


单例模式

__init__
__new__

线程安全模式,加上装饰器
https://github.com/Python3WebSpider/ProxyPool


单例

import threading

"""
如果一个对象,具备__enter__(),__exit__(),就可以配合with来使用
__enter__()的返回值会交给as后的目标
无论with代码块在执行过程中是否会发生异常,都会在最终执行 __exit__()方法
"""


# class Test():
#
#     def __enter__(self):
#         print("初始化")
#         return "haha"
#
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         print("关闭资源")


# with Test() as t:
#     print(t)

class Singleton(object):
    instance = None

    def synchronized(func):
        func.__lock__ = threading.Lock()

        def synced_func(*args, **kws):
            with func.__lock__:
                return func(*args, **kws)

        return synced_func

    @synchronized
    def __new__(cls):
        # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象
        if not cls.instance:
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值