常见的反爬机制以及图片验证码识别

反爬虫的各种方式


从具体手段上来看,反爬虫包括很多方式:

  1. 识别Request Headers,这是很基础的反扒手段,主要通过验证headers中的User-Agent信息来判断当前访问是否来自常见的界面浏览器.更复杂的headers验证则会要求验证Referer、Accept-encoding 等信息.
  2. 使用 Ajax动态加载 ,严格来说不是一种为反爬而生的手段,但是使用了动态页面,如果只是简单的静态网页源代码解析工具,就能起到保护数据的作用
  3. 验证码机制,当用户异常访问时,会弹出验证码识别,比如短时间收内受到频次异常高的时候,是一种具有普遍应用场景的安全措施,这无疑是反爬中重要的一环
  4. 更改服务器返回的信息,通过数据加密返回虚假信息等方式保护服务器返回的信息,避免被直接抓取,一般搭配 Ajax 使用,比如现在的boss直聘信息招聘页面
  5. 限制或封禁IP地址,这是反爬机制最主要的‘‘触发后动作’’,判定为爬虫后,就限制或者封禁 来自当前ip的访问
  6. 修改URL或网页内容,尽量令其复杂化,甚至通过对普通用户隐藏某些元素和输入方式来区别用户和爬虫
  7. 账号限制,只有已登录的账号才能访问网站

反反爬之 伪装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对象: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)

posted @ 2022-03-16 21:44  Milo_Carey  阅读(961)  评论(0)    收藏  举报