[华为云在线课程][Python网络爬虫][爬虫优化及反爬][六][学习笔记]
1.优化
1.1.爬虫效率
在使用爬虫获取大量数据时,会存在一些速率上的限制条件:
- 服务器性能
- 网络带宽
- 多线程、多进程
- IO操作
- 同步和异步
- 遍历算法
1.2.爬虫效率优化
硬件优化:
- 增加网络带宽
- 提升服务器硬件,用来支持更多的线程与进程
程序优化:
- 异步非阻塞IO
- 深度优先、广度优先等算法
- 多进程、多线程和协程
分布式爬虫
1.3.多线程爬虫优化
通过使用多线程的方式来实现提高爬虫获取数据的效率。
1.4.线程
- 线程是操作系统的最小执行单元。
- 在一个进程内的所有线程共享全局变量。
- 因为全局解释器锁的缘故,Python中的多线程是一个伪多线程。
- GIL(Global Interpreter Lock,全局解释器锁):Python中为了解决多线程之间的数据完整性和状态同步问题准备的锁。
1.5.线程同步
- 如果多个线程同时对一个全局变量操作,会出现资源竞争问题,导致数据错误。为了解决这个问题,需要进行线程同步。
- 线程同步是指多个线程按先后顺序执行。实现线程同步则需要引入锁的机制。
- 互斥锁:在线程执行时对资源加互斥锁,使得其他线程无法操作资源,直到该线程释放资源后,将锁打开,其他线程才能对资源进行操作。
- 死锁:多个线程共享资源时,几个线程分别占有一部分资源并且等待其他线程的资源时,就会造成死锁。
1.6.Python多线程实现
Python中的多线程通过threading模块实现。
threading模块常用方法:
- threading.Thread(target):创建线程,通过target参数指定线程执行的函数。
- T.start():启动线程(T代表创建好的线程)
- threading.Lock:创建互斥锁。
- L.acquire():线程加锁。(L为创建好的锁)
- L.release():线程解锁。
1.7.进程
- 进程是操作系统的最小资源分配单元。
- 一个程序至少拥有一个进程,一个进程至少拥有一个线程。
- 同一进程中的线程数据共享。
- 每个进程拥有独立的内存空间。
1.8.Python多进程实现
Python中通过模块multiprocessing来实现多进程。
multiprocessing模块常用方法:
- multiprocessing.Process(target):创建子进程(通过target指定子进程执行的函数)。
- P.start():启动子线程(P为一个子进程)。
- P.terminate():终止子进程。
1.9.消息队列
- 消息队列可以当做是一个消息的容器,在使用多线程或者多进程实现高效率爬取时,为了避免重复的URL爬取,除去对线程加锁以外还可以使用消息队列来存储带爬取的URL。
- Python中通过Queue模块来实现消息队列。
- Q = Queue(n):初始化消息队列,n为接受的消息数据量。
- Q.put:写入一条消息。
- Q.get:取出消息。
1.10.爬虫URL优化
URL去重:网页中存在很多的超链接,连接对应的网站也会是我们爬取数据的对象,但是网页中多个超链接所对应的URL可能会出现数据一致的情况,及时将重复的URL去掉可以提高效率。
- 使用集合的形式去保存网页中获取的URL。
- 给URL增加唯一标识。
2.反爬
2.1.网站反爬
- 正常用户的网站访问可以增加网站的知名度,增加网站的用户流量,所以网站会做SEO优化,方便通用爬虫程序(浏览器)找到自己,提高点击量。
- 聚焦爬虫程序会在短时间内产生大量的访问,可以达到每秒钟进行上千次的访问,这是正常用户达不到的操作,会增加网站的服务器压力。所以网站一般会设置有反爬措施防止爬虫程序(爬取数据的聚焦爬虫)访问。
2.2.常见的反爬措施
爬虫程序是模拟浏览器进行数据获取的,所以常见的反爬措施便是针对爬虫程序和浏览器的不同进行的。
- Headers字段:浏览器在发送请求时所带有的信息,包括浏览器信息user-agent,用户cookie信息等。通过检查headers字段判别爬虫程序。
- ip地址:用户发送请求时所使用的ip地址。通过ip地址限制进行反爬。
- 异常数据:通过js代码将数据进行修改,返回给爬虫程序错误的数据。
- 字体:使用自定义格式的字体,使爬虫无法解析数据,从而获取到乱码数据。
- 隐藏参数:通过js发送隐藏参数,验证是否是正常用户。
- …
2.3.Headers字段
Headers字段是爬虫程序伪装成浏览器用户的最为基础也是最为重要的一点,几乎所有的网站都会对headers进行反爬。
2.4.Headers字段详解
cookie:用户信息的缓存。
host:目标主机地址,即服务器地址。
referer:上一个url,即从哪个网址跳转过来的。
User-Agent:浏览器信息,包含了浏览器内核版本等信息。
2.5.User Agent
User Agent(简称UA),网站常常通过判断UA来给不同的操作系统、不同的浏览器发送不同的页面。
标准格式为:浏览器标识(操作系统标识;加密等级标识;浏览器语言)渲染引擎标识,版本信息。
- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.41
如果爬虫程序不加UA,默认为Python的版本信息。
2.6.Headers使用注意事项
正常用户在访问时的频率每秒钟大概只有1-5次,在设置headers时需要注意:
- cookie:每个cookie代表一个用户,短时间内的高速访问可设置多个cookie信息,通过轮流使用避免反爬。
- referer:大多数网站并不对此字段反爬,可以选择不设置。
- User-Agent:和cookie一样,需要设置多个。因为浏览器信息是不变的,可以收集多个浏览器的User-Agent轮流使用,而且不需要做过多的维护。
2.7.IP地址
- IP地址就是给每个连接在互联网上的主机分配的一个32位地址。
- IP地址就好像电话号码(地址码):有了某人的电话号码,就可以进行会话。同样,有了某台主机的IP地址,就能与这台主机通信。
- 在爬取数据发送请求的时候,爬虫程序也会携带IP地址进行访问,如果被识别为爬虫程序可能会被封IP,短时间无法再请求对方网站(405,503警告)。
2.8.代理IP介绍
- 代理IP即代理服务器(Proxy Server),功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中转站,是个人网络和Internet服务商之间的中间代理机构,负责转发合法的网络信息,对转发进行控制和登记。
- 使用代理IP可以让服务器以为不是同一个客户端在请求。
- 代理IP可以防止真实地址泄露。
- 代理IP如果被封,并不会影响真实的IP地址的访问。
2.9.代理IP
代理IP的分类:
- 透明代理:透明代理直接隐藏你的IP地址,但是可以查到你是谁。
- 匿名代理:使用匿名代理,别人只能知道你用了代理,无法知道你是谁。
- 高匿代理:高匿代理让别人根本无法发现你是在用代理,是最好的选择。
代理IP的工作流程如下图所示:
2.10.代理IP注意事项
- 代理IP协议:http代理、https代理、socket代理,不同分类的代理,在使用的时候需要根据抓取网站的协议来选择。
- 代理IP的获取:可以通过第三方进行购买,购买后需要进行测试时候可以使用;也可以通过一些网站获取免费的代理IP,但是质量会比较低,使用时长较短。
2.11.验证码
- 验证码(CAPTCHA)是"Completely Automated Public Turing test to tell Computers and Humans Apart"(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式。
- 爬虫程序是无法像人一样区分是识别验证码,能取到很好的反爬作用。
2.12.常见的验证码
2.13.验证码的破解方式
- 图像解码、深度学习:通过建立深度神经网络让程序自动去识别验证码。
- 打码平台:由于验证码图像生成技术无论成本和难度都要远远低于图像解码识别技术,最后解码技术从自动化逐渐转变成雇佣人去解码,而不是研发新的解码系统。
- 使用一些封装好的工具包:Tesseract-OCR。
- 使用selenium工具包模拟鼠标点击效果,实现滑块拖动(适用于极验验证码)。
2.14.JavaScript动态参数
通过JavaScript动态生成参数,参数在浏览器加载页面的时候生成,并作为表单数据中一个数据一同发送给目标主机进行验证。爬虫程序并不会生成这个参数,会被目标主机识别为爬虫程序。比如,百度翻译中的sign值。
2.15.模拟js参数生成
在Python代码中可以使用工具包来执行js代码,生成动态参数。
- Execjs
- PyV8
- Selenium
- node
2.16.字体反爬
自定义字体:某些网站使用自己的字体,导致爬虫程序获取的数据没有办法直接解析。比如猫眼电影中的电影评分。
2.17.其他反爬措施
- 用户行为检测:检测鼠标移动和点击方式。
- URL加密:对数据URL进行加密。
- 蜜罐:目标主机识别为爬虫程序后,返回虚假错乱的数据。
- 点赞
- 收藏
- 关注作者
评论(0)