常见的反爬机制以及图片验证码识别
反爬虫的各种方式
从具体手段上来看,反爬虫包括很多方式:
- 识别Request Headers,这是很基础的反扒手段,主要通过验证headers中的
User-Agent信息来判断当前访问是否来自常见的界面浏览器.更复杂的headers验证则会要求验证Referer、Accept-encoding 等信息. - 使用
Ajax和动态加载,严格来说不是一种为反爬而生的手段,但是使用了动态页面,如果只是简单的静态网页源代码解析工具,就能起到保护数据的作用 验证码机制,当用户异常访问时,会弹出验证码识别,比如短时间收内受到频次异常高的时候,是一种具有普遍应用场景的安全措施,这无疑是反爬中重要的一环- 更改服务器返回的信息,通过
数据加密、返回虚假信息等方式保护服务器返回的信息,避免被直接抓取,一般搭配 Ajax 使用,比如现在的boss直聘信息招聘页面 - 限制或封禁IP地址,这是反爬机制最主要的‘‘触发后动作’’,判定为爬虫后,就限制或者封禁 来自当前ip的访问
- 修改URL或网页内容,尽量令其复杂化,甚至通过对普通用户隐藏某些元素和输入方式来区别用户和爬虫
- 账号限制,只有已登录的账号才能访问网站
反反爬之 伪装headers
下边列出了几个 Request Headers 中常用的信息
| 常见字段名 | 含义 |
|---|---|
| Accept | 指定客户端能够接受的内容类型 |
| Accept-Encoding | 浏览器可以支持的Web服务器返回内容压缩编码类型 |
| Accept-Lanuage | 浏览器可以接受的语言 |
| Connection | 是否需要持久链接 |
| Host | 指定请求的服务器主机的域名和端口号等 |
| Referrer | 先前网页的地址 |
| User-Agent | 包含发出的请求的用户信息,主要是浏览器信息 |
-
其中最常用的就是
UA伪装,把对应User-Agent封装到一个字典中,在request.get()方法中传入 -
UA的获取:
- 在network中的任意请求信息中复制
F12->network->Headers->Request Headers
- 通过第三方库伪装
pip install fake_useragent
import fake_useragent
ua = fake_useragent.UserAgent( )
headers = {
'User-Agent': ua.chrome
}
-
然后就是防盗链 referer 的伪装,典型的就是 梨视频 的反爬
-
referer 溯源,获取先前网页的地址
-
直接丢到 headers 中,和 UA 一样
反反爬之 Ajax 动态加载
当我们爬取一个网页的部分内容时候,发现爬取下来的是空或者不存在,就要考虑是不是动态加载的内容
比如爬取好看视频(‘https://haokan.baidu.com/?sfrom=baidu-top’)
当查看页面源码时,并没有内容,就说明是动态加载的
解决方法:
F12->network->Fewtch/XHR (XHR:过滤网页中Ajax请求中包含的URL)
在 Preview 找到你需要的数据 点击Headers 找到Request URL 对其发送GET请求
在Headers下的Response Headers下的Content-Type可以看到返回类型是json
实现代码如下:
import requests
import fake_useragent
from lxml import etree
ua = fake_useragent.UserAgent( )
url = ' https://haokan.baidu.com/web/video/feed?tab=recommend&act=pcFeed&pd=pc&num=22&shuaxin_id=1647433246818'
headers = {
'User-Agent':ua.chrome
}
response = requests.get(url=url, headers=headers)
page = response.json()
print(page)
反反爬之 验证码解析
推荐使用第三方打码平台
这里使用的是超级鹰(主要是便宜)
注册登录之后 在开发文档下载对应语言(python)的rar包
将里边的chaojiying.py放到你的爬虫文件目录下
更改chaojiying.py最后一行的内容,里边有提示
在爬虫文件中的使用:
# 在使用打码工具之前先导入chaojiying的py文件的Chaojiying_Client类
from chaojiying import Chaojiying_Client
# 输入在网页上注册的用户名密码,以及生成的软件ID
chaojiying = Chaojiying_Client('超级鹰用户名', '超级鹰用户名的密码', '软件ID')
# img是打开以后的图片
# 1902是识别的验证码类型,可以在网页上的价格体系里面能看到
# chaojiying.PostPic在这一步进行了识别
# dic是识别以后的数据,其中有很多其他的信息
dic = chaojiying.PostPic(img, 1902)
# 需要的验证码数据在dic中的pic_str的键对应的value
# verify_code是最终需要的验证码
verify_code = dic[]"pic_str"]
# 把verify_code填到需要的地方
反反爬之 js逆向解析
有些网站的内容是经过数据加密的,比如boss直聘
需要通过 js逆向解析
目前不会
反反爬之 封禁ip
可以使用代理IP进行网站数据的爬取
在reqest.get中添加参数proxies={‘http’:’http://ip:port’}
response = requests.get(url=url, headers=headers,proxies={'http':'http://121.232.148.26:9000'})
反反爬之 账号限制
- 通过post请求携带参数 使用session登录
http/https协议特性:无状态
没有请求到对应数据的原因:
发起的第二次基于个人主页请求时,服务器并不知道该次请求时基于登录状态下的请求
cookie:让服务器保留客户端的相关状态
- 通过抓包工具手动处理cookie封装到headers中
- cookie时模拟登陆psot后,由服务器端创建
- session会话对象
- 进行请求发送
- 如果请求过程中产生了cookie,则cookie会被自动存储/携带到session对象中
- session会话对象
- 创建session对象:request.Session()
- 使用session对象进行模拟登陆post请求发送
- session进行get请求发送(携带cookie)
# -*-coding:utf-8-*-
import requests
from lxml import etree
from chaojiying import Chaojiying_Client
if __name__ == "__main__":
# 创建一个session对象
session = requests.Session()
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
}
url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
page_txt = session.get(url=url,headers=headers).text
# 解析img的src的zhi
tree = etree.HTML(page_txt)
src = 'https://so.gushiwen.cn' + tree.xpath('//*[@id="imgCode"]/@src')[0]
img_data = session.get(url = src,headers=headers).content
chaojiying = Chaojiying_Client('超级鹰账号', '超级鹰密码', '软件ID')
dic = chaojiying.PostPic(img_data, 1902)
code = dic["pic_str"]
login_url = 'https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx'
data={
'__VIEWSTATE': 'gBVayz6 / Fp6Yz2JMFpdRAYclMzJDgyBrLu8SbsEttWCMF9wc8vxeoB6ZWl7gUyyc9zRqeCRNQNn44WGoqL5yrKi85ff84dAiva + yPVTdl7mplq6s7qaOffXZd / 0 =',
'__VIEWSTATEGENERATOR' : 'C93BE1AE',
'from': 'http: // so.gushiwen.cn / user / collect.aspx',
'email': '古诗文网账号',
'pwd': '古诗文密码',
'code': code,
'denglu': '登录',
}
#使用session进行post请求的发送
login_txt = session.post(url=login_url,headers=headers,data=data)
print(login_txt.status_code)
user_url = 'https://so.gushiwen.cn/user/collect.aspx'
#使用携带cookie的session进行请求
user_txt = session.get(url=user_url,headers=headers).text
with open('user.html', 'w') as f:
f.write(user_txt)

浙公网安备 33010602011771号