爬虫速度优化、Python多线程、adsl拨号解决ip被封问题

爬虫速度优化

  1. 优化硬盘存储:每个网页大概多大,加起来以后会有多大,需不需要压缩存储
  2. 优化内存,url去重:减少所有url放在一起去重时,内存不够用情况,使用bloomFilter算法,查询效率高
  3. 反抓取访问频率限制:
    • 研究网站的反爬策略
    • 多ip抓取:IP代理池和adsl拨号
      • IP代理池:比较贵
      • ADSL拨号:便宜,但速度可能稍微慢一些
  4. 网络性能,抓取技术细节调优
    • 开多个线程,探索多长时间/多少频率切换拨号ip最优:

      • 需要对网站的反爬策略进行测试。先开一个线程,一直抓到ip被屏蔽,记录下抓取耗时,总抓取词数和成功抓取词数。再开两个线程/4个线程,重复上面的步骤,统计抓取极限和细节调优的表格。
      • 开线程由于有全局锁的存在,其实还是串行的,所以速度上没有太大的优势。使用多进程。
      • 单个ip、单个cookies多测几次,得到一个大概的值,再进行优化。
    • requests请求优化:设置超时放弃时间requests.get(url, timeout=(5, 10)),二次请求可能比一直在等待的抓取效率高一些
    • 优化ADSL拨号等待时间:
      • 每次断开拨号后,要等待几秒钟再拨号,太短时间内拨号有可能又拨到上一个ip或者失败,所以要等待几秒钟再拨。
      • 拨完号后,需要检测一下外网是否连通,使用ping功能或requests检测外网的连通性以及代理的可用性。
  5. 注意事项:
    • 要计算对方的带宽压力,不要抓取的太过分,以致于影响对方网站的正常运转。
需要了解的一些东西
  1. 多线程和多进程分别是什么?有什么的区别?有什么优缺点?分别适用于什么场景?怎么用?

    1. 多线程和多进程是不一样的!一个是 thread 库,一个是 multiprocessing 库
    2. 多线程
      1. GIL的全称是Global Interpreter Lock(全局解释器锁), 某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。而每次释放GIL锁,线程进行锁竞争、切换线程,会消耗资源。并且由于GIL锁存在,python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行),这就是为什么在多核CPU上,python的多线程效率并不高。在Python2.x里,GIL的释放逻辑是当前线程遇见IO操作或者ticks计数达到100(ticks可以看作是Python自身的一个计数器,专门做用于GIL,每次释放后归零,这个计数可以通过 sys.setcheckinterval 来调整),进行释放。
      2. CPU密集型代码(各种循环处理、计数等等),在这种情况下,由于计算工作多,ticks计数很快就会达到阈值,然后触发GIL的释放与再竞争(多个线程来回切换当然是需要消耗资源的),所以python下的多线程对CPU密集型代码并不友好。
      3. IO密集型代码(文件处理、网络爬虫等),多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能在线程A等待时,自动切换到线程B,可以不浪费CPU的资源,从而能提升程序执行效率)。所以python的多线程对IO密集型代码比较友好。
      4. 而在python3.x中,GIL不使用ticks计数,改为使用计时器(执行时间达到阈值后,当前线程释放GIL),这样对CPU密集型程序更加友好,但依然没有解决GIL导致的同一时间只能执行一个线程的问题,所以效率依然不尽如人意。
      5. 多核多线程比单核多线程更差,原因是单核下多线程,每次释放GIL,唤醒的那个线程都能获取到GIL锁,所以能够无缝执行,但多核下,CPU0释放GIL后,其他CPU上的线程都会进行竞争,但GIL可能会马上又被CPU0拿到,导致其他几个CPU上被唤醒后的线程会醒着等待到切换时间后又进入待调度状态,这样会造成线程颠簸(thrashing),导致效率更低
    3. 多进程
      1. 每个进程有各自独立的GIL,互不干扰,这样就可以真正意义上的并行执行,所以在python中,多进程的执行效率优于多线程(仅仅针对多核CPU而言)。所以在这里说结论:多核下,想做并行提升效率,比较通用的方法是使用多进程,能够有效提高执行效率。
    4. 总结
      1. 多线程适用于单核机器、IO密集型代码;多核下,想要并行提高效率,一般用多进程。
  2. 自己没有做过的是URL降重和爬取质量的检测,这个之后要完善一下。
资料
  1. 使用adsl拨号服务器搭建代理池github精简操作地址另外一篇adsl参考
  2. 知乎关于反爬虫内容,主要看那个猿人学写的 adsl拨号方法获取ip启蒙文章。
  3. 进程与线程:
    1. 崔庆才 多进程用法异步协程多进程爬虫实战爬虫系列教程
    2. 100天Python系列进程、线程、协程
    3. 这个博客写的很清晰,补充材料
  4. 多进程问题:
    1. 捕捉进程中出现的异常get方法是可以将异常捕捉到,但是加了get()方法,程序就变成了阻塞的了,进程之间需要串行了,不是我们想要的结果
    2. get获取pool.apply_ssync()的结果的过程,最好放在进程池回收之后进行,避免阻塞后面的语句但是这样处理会使得异常在所有的进程都运行完了以后处理。这种办法适用于需要对多个进程的结果进行处理(加减乘除之类的),而不适用于处理异常,将程序停下来这种需求。
    3. multiprocessing pool 源码分析异常处理过程
    4. 最好的解决办法应该是,明确为什么这一步会出异常,并进行处理,进程不能在半路上停下来,在最终所有任务跑完以后再一起处理。
  5. 其他
    1. [requests 库用法](https://cuiqingcai.com/2556.html)
    2. [ubuntu安装与测试redis](https://www.cnblogs.com/wxjnew/p/9189191.html)
异常处理
  • 抓到异常应该把它抛到调用方法中去解决不是所有异常你都可以处理的,许多异常你就应该把它抛出到调用方去,如果你捕获住一个异常不往外抛,你就等于告诉调用方前面的过程没问题,可以继续往下走,但如果真的出现了问题,继续做下去往往会导致更严重的后果,通常都要比通过异常中止整个过程要糟糕。
redis 操作

sudo service redis-server restart
redis-cli
service redis status

vim 操作
  1. i 插入
  2. esc 推出编辑状态
  3. :q 退出;:wq 保存后退出;:q! 退出且强制不保存
  4. G 最后一行;nG 移动到第n行;0 这一行最前面的字符;$ 这一行最后面的字符;
  5. 搜索功能:/word 向下查找word这个单词;n 接着往下查找下一个word;N 反向查找word单词
Todo
  1. 更优雅的异常信息,使用logging,代替print

原文地址:https://www.cnblogs.com/YeEn/p/11707727.html

时间: 2024-10-08 07:55:28

爬虫速度优化、Python多线程、adsl拨号解决ip被封问题的相关文章

如何解决单IP被封后的反扒机制

单IP频繁爬取某网站,很容易被网站的反爬虫机制封掉IP,如何突破限制呢,答案是多IP爬虫.通过多IP爬虫,又分为以下几种形式: 1.通过ADSL拨号换IP.每拨一次就会有一个新IP,较好解决IP单一问题. 2.如果是局域网,带路由器的,第一种方法可能不好用.这个时候可以模拟登陆路由器,控制路由器重新拨号,换IP,这其实是一种折中的办法,曲线救国. 3.代理IP,利用购买的或者网上抓取的免费代理IP,实现多IP爬虫,这种形式是最常见的. 4.分布式爬虫.采用多个服务器,多个IP,多个slave爬虫

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

前言 我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理. 首先声明一点! 多线程和多进程是不一样的!一个是 thread 库,一个是 multiprocessing 库.而多线程 thread 在 Python 里面被称作鸡肋的存在!而没错!本节介绍的是就是这个库 thread. 不建议你用这个,不过还是介绍下了,如果想看可以看看下面,不想浪费时间直接看 multiprocessing 多进程 鸡肋点 名言: "Pyt

python多线程爬虫的简单例子

Python多线程(http://www.maiziedu.com/course/python/)主要是通过thread和threading这两个模块来实现的.thread模块是比较底层的模块,threading模块是对thread做了一些包装的,可以更加方便的使用. 虽然python的多线程受GIL限制,并不是真正的多线程,但是对于I/O密集型计算还是能明显提高效率,比如说爬虫. 下面用一个实例来验证多线程的效率.代码只涉及页面获取,并没有解析出来. # -*-coding:utf-8 -*-

python多线程爬虫设计及实现示例

爬虫的基本步骤分为:获取,解析,存储.假设这里获取和存储为io密集型(访问网络和数据存储),解析为cpu密集型.那么在设计多线程爬虫时主要有两种方案:第一种方案是一个线程完成三个步骤,然后运行多个线程:第二种方案是每个步骤运行一个多线程,比如N个线程进行获取,1个线程进行解析(多个线程之间切换会降低效率),N个线程进行存储. 下面我们尝试抓取http://www.chembridge.com/ 库存药品信息. 首先确定url为http://www.chembridge.com/search/se

python多线程爬虫+批量下载斗图啦图片项目(关注、持续更新)

python多线程爬虫项目() 爬取目标:斗图啦(起始url:http://www.doutula.com/photo/list/?page=1) 爬取内容:斗图啦全网图片 使用工具:requests库实现发送请求.获取响应. xpath实现数据解析.提取和清洗 threading模块实现多线程爬虫 爬取结果: 思路:由于该爬虫存在网络密集IO和磁盘密集IO,存在大量等待时间,遂采用多线程方式爬取. 设计:本文采用多为结构化代码的面向对象封装设计思路,使用生产消费者模型,完成多线程的调度.爬取.

pytohn爬虫成长之路:抓取代理IP并多线程验证

上回说到,突破反爬虫限制的方法之一就是多用几个代理IP,但前提是我们得拥有有效的代理IP,下面我们来介绍抓取代理IP并多线程快速验证其有效性的过程. 一.抓取代理IP 提供免费代理IP的网站还挺多的,我在'西刺代理'上一阵猛抓后自己的IP就被其屏蔽了.只好换'IP巴士'并乖乖的减缓抓取速度了.贴上抓取代码 import urllib.request import urllib import re import time import random #抓取代理IP ip_totle=[] #所有页

Python多线程与多进程(一)

多线程 多线程是程序在同样的上下文中同时运行多条线程的能力.这些线程共享同一个进程的资源,可以在并发模式(单核处理器)或并行模式(多核处理器)下执行多个任务 多线程有以下几个优点: 持续响应:在单线程的程序中,执行一个长期运行的任务可能会导致程序的冻结.多线程可以把这个长期运行的任务放在一个线程中,在程序并发的运行任务时可以持续响应客户的需求 更快的执行速度:在多核处理器的操作系统上,多线程可以通过真正的并行提高程序的运行速度 较低的资源消耗:利用线程模式,程序可以利用一个进程内的资源响应多个请

HBase 高性能获取数据 - 多线程批量式解决办法

在前篇博客里已经讲述了通过一个自定义 HBase Filter来获取数据的办法,在末尾指出此办法的性能是不能满足应用要求的,很显然对于如此成熟的HBase来说,高性能获取数据应该不是问题.下面首先简单介绍了搜索引擎的性能,然后详细说明了HBase与MySQL的性能对比,这里的数据都是经过实际的测试获得的.最后,给出了采用多线程批量从HBase中取数据的方案,此方案经过测试要比通过自定义Filter的方式性能高出很多. Solr和HBase专辑 1.“关于Solr的使用总结的心得体会”(http:

Python多线程和多进程谁更快?

python多进程和多线程谁更快 python3.6 threading和multiprocessing 四核+三星250G-850-SSD 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很多都说python多进程更快,因为GIL(全局解释器锁).但是我在写代码的时候,测试时间却是多线程更快,所以这到底是怎么回事?最近再做分词工作,原来的代码速度太慢,想提速,所以来探求一下有效方法(文末有代码和效果图) 这里先来一张程序的结果图,说明线程和进程谁更快 一些定义 并行是指两个或者多个事件