打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
某麒麟网站模拟登录(验证码识别)
userphoto

2022.08.12 广东

关注
作者:TheWeiJun
来源:逆向与爬虫的故事

阅读本文大概需要 7 分钟。

 目录

一、前言介绍
二、模拟登录
三、参数分析
四、代码实现
五、思路总结

趣味模块

      小军是一名 spider 工程师,最近有个新的需求,领导希望小军能够写一个模拟登录,完成每天定时导出报表工作。小军拿到领导给的任务后,马上开始写代码,但是在模拟登录过程中遇到了验证码。接下来咱们一起去看看小军是如何实现的模拟登录和解决的验证码识别吧!


一、前言介绍

1.  什么是模拟登录?

解释:网页上以及 app 中输入账号密码的过程称为登录,不经过登录有些页面是无法直接跳转的。而模拟登录就是模拟手动输入账号密码的过程,获得登录成功后的 cookie,以此 cookie 直接访问需要登录才能进入的页面,从而获取数据。

2.  什么是 Cookie?

解释:cookie 是某些网站为了辨别用户身份,进行 Session 跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。

3.  什么是 Session?

解释:Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是 Session。客户端浏览器再次访问时只需要从该 Session 中查找该客户的状态就可以了。


二、模拟登录

1、找到我们本次需要模拟登录的网站,打开网页,截图如下所示:

2、完成模拟登录操作,浏览器查看相关请求包,截图如下所示:

环节说明:因为我们想要获取登录的协议接口,所以我们随便输入内容,可查看到模拟登录所需要的参数主要为上图四个。接下来,我们只需要模拟这四个参数即可实现模拟登录!


三、参数分析

1、参数初判断,需要我们模拟的参数主要有以下四个:

  • username:登录所需要的账号。

  • password:登录所需要的密码。

  • captcha:登录所需要的验证码。

  • _token:登录所需要的 token 认证。

2、验证码接口定位,打开网页源码,截图如下所示:

环节说明:在模拟登录过程中,我们需要访问首页页面的验证码才能保证和真实登录时候的验证码流程一致,否则会产生数据不同步问题产生。这个时候,实现模拟登录我们最好使用 session 保持会话,这样会避免一些干扰问题存在。

3、_token 参数模拟,表单提交时候需要同步的参数,截图如下所示:

环节说明:通过观察上图,我们可以看到其实这个参数其实也存在于首页页面中,其他网站的我觉得流程也类似,基本是通用的,我们只需要通过 xpath 提取即可!参数分析流程完毕后,接下来我们进入代码实现流程环节吧。


四、代码实现

1、验证码 url、_token 参数获取实现

def start_requests(self): response = self.request(self.auth_url) resp = etree.HTML(response) captcha_url = resp.xpath('//img[@class='captcha-img']/@src')[0] _token = resp.xpath('//input[@name='_token']')[0] token = _token.attrib.get('value')

代码运行后,终端输出信息如下:

2、验证码图片保存及识别实现

def get_captcha(self, captcha_url):    response = self.request(captcha_url)    text = self.ocr.recognition(response)   return text

环节说明:将刚刚获取的验证码url进行下载并提取验证码内容,与我们保存的图片进行比对,查看识别率是否准确。验证码识别模型训练我会在后面的文章中教大家如何实现!

运行当前代码,截图如下所示:

查看保存于本地的验证码,截图如下:

环节说明:此刻我们可以看到保存本地的验证和我们识别的文本内容完全一致,接下来上完整代码,再次运行看看是否能登录成功吧。

注意细节:最后模拟登录时的 url 和之前首页的 url 是一致的,只是请求的方式从 get 变成了 post

3、完整代码实现如下

# -*- coding: utf-8 -*-# ------------------------------# @author : 公众号:逆向与爬虫的故事# ------------------------------import requestsfrom lxml import etreefrom captcha_ocr import CaptchaOcr

class HuoSpider(object): def __init__(self): self.headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Origin': 'http://www.xxxx.com', 'Pragma': 'no-cache',            'Referer''http://www.xxxx.com/dgbak/auth/login', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', } self.auth_url = 'http://www.xxxx.com/dgbak/auth/login' self.session = requests.Session() self.ocr = CaptchaOcr()
def get_captcha(self, captcha_url): response = self.request(captcha_url) text = self.ocr.recognition(response) return text
def request(self, url, data=None): if data: resp = self.session.post(url=url, headers=self.headers, data=data, verify=False) else: resp = self.session.get(url=url, headers=self.headers, verify=False) return resp.content
def start_requests(self): response = self.request(self.auth_url) resp = etree.HTML(response) captcha_url = resp.xpath('//img[@class='captcha-img']/@src')[0] _token = resp.xpath('//input[@name='_token']')[0] token = _token.attrib.get('value') self.auth_requests(captcha_url, token)
def auth_requests(self, captcha_url, token): data = { 'username': '186******', 'password': '123456****', 'captcha': self.get_captcha(captcha_url), '_token': token, } response = self.request(self.auth_url, data=data) resp = etree.HTML(response) user_name = resp.xpath('//span[@class='hidden-xs']/text()') if user_name: print(f'登录后的用户名称: {user_name[0]}')

if __name__ == '__main__': hs = HuoSpider()    hs.start_requests()

代码 run 起来后,截图如下所示:

网站页面登录成功后,截图如下所示:

总结:对比上面两张截图,我们发现内容完全一致,此刻我们已经实现了模拟登录。


五、思路总结

回顾整个分析流程,本次难点主要概括为以下几点:

  • 如何快速定位到模拟登录的接口
  • 模拟每一个参数的生成并能实现
  • 如何实现对验证码内容文字的提取

  • 区分同一个 url 不同的 method 方法

今天分享到这里就结束了,欢迎大家关注下期文章,我们不见不散⛽️

End

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
如何用 Python 在京东上抢口罩
requests第三方库
接口测试框架——第三篇:发送(requests)
分享几段祖传的 Python 代码,拿来直接使用!
Python爬虫 - 抓取divnil动漫妹子图
HttpRunner3的HTTP请求是怎么发出去的
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服