zoukankan      html  css  js  c++  java
  • 爬虫.多线程爬虫与多进程爬虫

    多线程爬虫

      多线程的复杂性

       1.资源、数据的安全性:锁保护

       2.原子性:数据操作是天然互斥的

       3.同步等待:wait()、notify()、notifyAll()    #notify,通知

       4.死锁:多个线程对资源互锁,造成死锁

       5.容灾:任何线程出现错误,整个进程都会停止

      多线程的优势

       1.内存空间共享,信息数据交换效率高

       2.提高CPU的使用效率

       3.开发便捷

       4.轻,创建、销毁的开销小

      Python线程

        支持多线程(JavaScript PHP 不支持多线程)

        Python线程直接映射到native线程(Java1.4的Java线程是JVM实现的,共同运行在一个native thread)    #native,本地的  thread,线

        GIL:对于多核的利用能力有限

      实现一个多线程爬虫

        1.创建一个线程池threads=[ ]

        2.确认url队列线程安全 Queue Deque

        3.从队列取出url,分配一个线程开始爬取pop()/get()threading.Thread

        4.如果线程池满了,循环等待,直到有线程结束t.is_alive()

        5.从线程池移除已经完成下载的线程threads.remove(t)

        6.如果当前级别的url已经遍历完成,t.join()函数等待所有现场结束,然后开始下一级别的爬取

      多线程爬虫评价

        优势:1.有效利用CPU时间

           2.极大减少下载出错、阻塞对抓取速度的影响,整体上提高下载速度

           3.对于没有反爬虫限制的网站,下载速度可以多倍增加

        局限性:1.对于有反爬虫的网站,速度提升有限

            2.提高了复杂度,反编码要求更高

            3.线程越多,每个线程获得的时间就越少,同时线程切换更频繁也带来额外开销

            4.线程之间资源竞争更激烈

    多进程爬虫

      线程与进程

      多进程爬虫评估:

        目的:1.控制线程数量

           2.对线程进行隔离,减少资源竞争

           3.某些环境下,在单机上利用多个IP来伪装

        局限性:1.不能突破网络瓶颈

            2.单机的IP的情况下,变得没有意义

            3.数据交换的代价更大

      进程间通信

        管道(PIPE)

        信号(Signal):复杂

        消息队列:Posix及System V

        共享内存:速度最快,需要结合信号量达到进程间同步及互斥

        信号量:用于数据同步

        Socket:可以标准化,可以用于多机

      Android进程间通信Binder

      Android进程间通信AIDL

      创建多进程爬虫

        solution A-C/S模式    #solution,解决方案

        1.一个服务进程,入队及出队URL,入队需检查是否已经下载

        2.监控目前的爬取状态、进度

        3.多个爬取进程,从服务进程获取URL,并将新的URL返回给服务进程

        4.使用Socket来做IPC

      solution B-数据库模式

        1.使用数据库来读写爬取列表

        2.多个爬取进程,URL的获取与增加都通过数据库操作

      C/S  vs  数据库

        CS优势:1.运行速度快,添加、修改、查询都是内存的BIT位操作

             2.扩展方便。例如动态URL队列重拍

        数据库:1.开发便捷,数据库天生具备读写保护及支持IPC

            2.只需要写一个爬虫程序

      创建MySQL数据库表

      数据库创建

      Python MySQL connector      #connector,连接器

        使用MySQLConnectionPool来管理多线程下的mysql数据库连接

            mysql.connector.pooling.MySQLConnectionPool

            self.cnxpool.get_connection()

        _init_类实例的时候自动检查和创建数据库及表

        Cursor类:cursor=con.cursor(dictionary=Ture)  #cursor,光标

        SELECT...FOR UPDATE加读锁,避免多个进程取出同一个url

        cursor.commit()支持事物,默认关闭了autocommit因此需要提交    #commit提交

  • 相关阅读:
    【BZOJ1396】识别子串
    【BZOJ3309】DZY Loves Math
    【XSY3306】alpha
    整体二分
    常系数齐次线性递推
    【XSY2968】线性代数
    【XSY2892】【GDSOI2018】谁是冠军
    【BZOJ5020】[LOJ2289]【THUWC2017】在美妙的数学王国中畅游
    【XSY2989】字符串
    【XSY2988】取石子
  • 原文地址:https://www.cnblogs.com/jacky912/p/10521991.html
Copyright © 2011-2022 走看看