Python反爬虫防御机制与应对策略详解
本文深入解析网站常用的反爬虫技术,包括User-Agent与Referer检测、JavaScript混淆与动态渲染、IP频次限制及验证码机制。针对各项防御措施,提供Python环境下的具体绕过方案,如代理池轮换、Selenium模拟浏览器、PyV8执行JS及OCR识别等实战方法,帮助开发者理解并应对常见的反爬策略。
反爬虫背景与概述
网络爬虫是一种自动提取网页内容的程序,主要服务于搜索引擎,用于从万维网下载页面数据,是搜索引擎架构中的关键组件。然而,随着网络爬虫被滥用,互联网上充斥着大量同质化内容,原创者的权益难以保障。因此,越来越多的网站开始实施反网络爬虫策略,以保护其内容资产。
User-Agent与Referer检测及应对
一:User-Agent与Referer检测
User-Agent是HTTP协议中的一个字段,用于描述发出HTTP请求的终端设备的相关信息。
服务器通过该字段可以识别客户端使用的操作系统及其版本、CPU类型、浏览器及版本号、浏览器渲染引擎、语言设置以及安装的插件等详细信息。
基于这些信息,服务器能够判断访问者是否为正常浏览器用户,并对非正常浏览器的访问请求进行屏蔽。
解决方案:
通过伪装浏览器的User-Agent来绕过检测。由于不同浏览器的User-Agent字符串各异,且所有用户均可使用浏览器,因此在每次请求时动态切换浏览器的User-Agent,即可有效解决UA检测问题。
Referer是HTTP请求头的一部分。当浏览器向Web服务器发送请求时,通常会携带Referer字段,告知服务器请求来源页面。例如,某些图片网站在请求图片时会检测Referer值,若不符合要求,则不会返回正常的图片资源。
解决方案:
在发送包含Referer检测的请求时,手动构造并携带符合要求的Referer值。
JavaScript混淆与渲染处理
二:JavaScript混淆与渲染
JavaScript混淆主要包含以下操作:
1. 移除未实际调用的函数。
2. 合并零散的变量声明。
3. 精简逻辑函数。
4. 简化变量名。具体策略取决于所使用的压缩工具,常见的工具有UglifyJS、JScrambler等。
JS渲染是指对HTML页面进行修改的过程。部分网页在初始加载时不返回数据,而是通过JavaScript加载后动态插入HTML中。由于普通爬虫无法执行JavaScript代码,因此需要采用其他技术手段来处理此类情况。
解决方案:
1. 阅读网站JavaScript源码,定位关键代码逻辑,并使用Python重新实现。
2. 阅读网站JavaScript源码,定位关键代码,利用PyV8、execjs等库直接执行JavaScript代码。
3. 使用Selenium库模拟完整的浏览器运行环境。
IP频率限制与代理策略
三:IP频率限制
Web系统通过HTTP协议与Web容器通信,每次请求至少建立一次客户端与服务器的TCP连接。
服务端可以清晰地监控到特定IP地址在单位时间内的请求数量。
当请求数量超过设定阈值时,系统可判定为非正常用户请求并进行限制。
解决方案:
1. 自行构建IP代理池,通过轮换机制,确保每次请求携带不同的代理地址。
2. 利用ADSL动态拨号技术,其特点是每次拨号都会获取一个新的IP地址,从而实现IP的动态变化。
验证码机制与识别方案
四:验证码机制
验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种自动化的公共程序,用于区分用户是计算机还是人类。
验证码可用于防止:恶意破解密码、刷票、论坛灌水,有效阻止黑客通过特定程序对特定注册用户进行暴力登录尝试。
验证码由计算机生成并评判,但只有人类才能解答。由于计算机无法解答CAPTCHA问题,因此能正确回答的用户被视为人类。
解决方案:
1. 手动识别验证码。
2. 使用pytesseract库识别简单的验证码。
3. 对接第三方打码平台。
4. 应用机器学习技术进行识别。
扩展知识:
基于反爬的相关实例代码:
Python反爬虫实战代码示例
#! /usr/bin/env python3.4
#-*- coding:utf-8 -*-
#__author__ == "tyomcat"
import urllib.request
import random
import re
url='http://www.whatismyip.com.tw'
iplist=['121.193.143.249:80','112.126.65.193:80','122.96.59.104:82','115.29.98.139:9999','117.131.216.214:80','116.226.243.166:8118','101.81.22.21:8118','122.96.59.107:843']
proxy_support = urllib.request.ProxyHandler({'http':random.choice(iplist)})
opener=urllib.request.build_opener(proxy_support)
opener.addheaders=[('User-Agent','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36')]
urllib.request.install_opener(opener)
response = urllib.request.urlopen(url)
html = response.read().decode('utf-8')
pattern = re.compile('<h1>(.*?)</h1>.*?<h2>(.*?)</h2>')
iterms=re.findall(pattern,html)
for item in iterms:
print(item[0]+":"+item[1])
#! /usr/bin/env python
# -*- coding:utf-8 -*-
#__author__ == "tyomcat"
from selenium import webdriver
import time
import re
drive = webdriver.PhantomJS(executable_path='phantomjs-2.1.1-linux-x86_64/bin/phantomjs')
drive.get('https://mm.taobao.com/self/model_info.htm?user_id=189942305&is_coment=false')
time.sleep(5)
pattern = re.compile(r'<div.*?mm-p-domain-info">.*?class="mm-p-info-cell clearfix">.*?<li>.*?<label>(.*?)</label><span>(.*?)</span>',re.S)
html=drive.page_source.encode('utf-8','ignore')
items=re.findall(pattern,html)
for item in items:
print item[0],'http:'+item[1]
drive.close()
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













