使用图鉴 API 实现 js 脚本自动登录实践

简介: 通过调用图鉴图像识别 API 解析图片验证码实现网页 js 脚本自动登录

登录页 form 表单

<form action="/" id="loginForm" method="post" role="form">
    <div class="dl box-shadow1">
        <div class="dl-bj space-m ">
            <div class="dl-box space-m">
                <div class="dl-box-left float-l">
                    <div class="dl-box-left-text">
                        <div class="neme float-l">用户名</div>

                        <input class="text1 float-l" id="UserAccount" name="UserAccount" type="text"
                            autocomplete="off" value="" />
                    </div>
                    <div class="dl-box-left-text space-m-t-05">
                        <div class="neme float-l">密 码</div>

                        <input class="text2 float-l" id="Password" name="Password" type="password"
                            autocomplete="off" value="" />
                    </div>
                    <div class="float-l" style="width:372px">
                        <table>
                            <tr>
                                <td>
                                    <div class="dl-box-left-textyzm space-m-t-05">
                                        <div class="neme float-l">验证码</div>
                                        <input class="text3" id="SecurityCode" name="SecurityCode"
                                            type="text" autocomplete="off" value="" />
                                    </div>
                                </td>
                                <td>
                                    <div class="neme"><img style=" margin-top:4px;border-radius:5px;"
                                            onclick="this.src= document.location.protocol + '/Account/GetSecurityCode?flag=' + Math.random(); "
                                            id="secImg" title="换一张" /></div>
                                </td>
                            </tr>
                        </table>

                    </div>
                    <br />
                    <div class="err">
                        <div class="ts">
                            <font size="2" color="#fff">
                                验证码错误,请重新输入!
                            </font>
                        </div>
                    </div>
                </div>
                <div class="dl-box-right float-r">
                    <input id="btnLogin" class="label-2 radius-5 pointer space-m-b-10 space-m" type="button"
                        value="登 录" />
                </div>
                <div class="clear"></div>
            </div>
        </div>
    </div>
</form>

自动登录 js 脚本

// XMLHttpRequest 请求网络封装方法
const http = {
    ajax: (settings = {}) => {
        let _s = Object.assign ({
            url: '', // string
            type: 'GET', // string 'GET' 'POST' 'DELETE'
            dataType: 'json', // string 期望的返回数据类型:'json' 'text' 'document' 'blob'...
            async: true, // boolean true:异步请求 false:同步请求 required
            data: null, // any 请求参数,data需要和请求头Content-Type对应
            headers: {}, // object 请求头
            timeout: 1000, // string 超时时间:0表示不设置超时
            beforeSend: (xhr) => {},
            success: (result, status, xhr) => {},
            error: (xhr, status, error) => {},
            complete: (xhr, status) => {}
        }, settings);
        // 参数验证
        if (!_s.url || !_s.type || !_s.dataType || _s.async === undefined) {
            alert('参数有误');
            return;
        }
        // 创建XMLHttpRequest请求对象
        let xhr = new XMLHttpRequest();
        // 请求开始回调函数
        xhr.addEventListener('loadstart', e => {
            _s.beforeSend(xhr);
        });
        // 请求成功回调函数
        xhr.addEventListener('load', e => {
            const status = xhr.status;
            if ((status >= 200 && status < 300) || status === 304) {
                let result;
                if (xhr.responseType === 'text') {
                    result = xhr.responseText;
                } else if (xhr.responseType === 'document') {
                    result = xhr.responseXML;
                } else {
                    result = xhr.response;
                }
                // 注意:状态码200表示请求发送/接受成功,不表示业务处理成功
                _s.success(result, status, xhr);
            } else {
                _s.error(xhr, status, e);
            }
        });
        // 请求结束
        xhr.addEventListener('loadend', e => {
            _s.complete(xhr, xhr.status);
        });
        // 请求出错
        xhr.addEventListener('error', e => {
            _s.error(xhr, xhr.status, e);
        });
        // 请求超时
        xhr.addEventListener('timeout', e => {
            _s.error(xhr, 408, e);
        });
        let useUrlParam = false;
        let sType = _s.type.toUpperCase ();
        // 如果是"简单"请求,则把data参数组装在url上
        if (sType === 'GET' || sType === 'DELETE') {
            useUrlParam = true;
            _s.url += http.getUrlParam(_s.url, _s.data);
        }
        // 初始化请求
        xhr.open(_s.type, _s.url, _s.async);
        // 设置期望的返回数据类型
        xhr.responseType = _s.dataType;
        // 设置请求头
        for (const key of Object.keys(_s.headers)) {
            xhr.setRequestHeader(key, _s.headers[key]);
        }
        // 设置超时时间
        if (_s.async && _s.timeout) {
            xhr.timeout = _s.timeout;
        }
        // 发送请求.如果是简单请求,请求参数应为null.否则,请求参数类型需要和请求头Content-Type对应
        xhr.send(useUrlParam ? null : http.getQueryData(_s.data));
    },
    // 把参数data转为url查询参数
    getUrlParam: (url, data) => {
        if (!data) {
            return '';
        }
        let paramsStr = data instanceof Object ? http.getQueryString(data) : data;
        return (url.indexOf('?') !== -1) ? paramsStr : '?'+paramsStr;
    },
    // 获取ajax请求参数
    getQueryData: (data) => {
        if (!data) {
            return null;
        }
        if (typeof data === 'string') {
            return data;
        }
        if (data instanceof FormData) {
            return data;
        }
        return http.getQueryString(data);
    },
    // 把对象转为查询字符串
    getQueryString: (data) => {
        let paramsArr =[];
        if (data instanceof Object) {
            Object.keys(data).forEach(key => {
                let val = data[key];
                // todo 参数Date类型需要根据后台api酌情处理
                if (val instanceof Date) {
                    // val = dateFormat(val, 'yyyy-MM-dd hh:mm:ss');
                }
                paramsArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
            });
        }
        return paramsArr.join('&');
    }
}
// 从 Bolb 中读取 Base64 图片数据方法
function blobToBase64(blob, callback) {
   var reader = new FileReader();
   reader.onload = function (e) {
       callback(e.target.result);
   }
   reader.readAsDataURL(blob);
}
// 自动登录方法
function auto_login() {
    // 替换自己的账户 input 和账户名称
    document.getElementById('UserAccount').value = 'xxxxxxxx';
    // 替换自己的密码 input 和账户密码
    document.getElementById('Password').value = 'xxxxxx';
    // 替换自己的验证码 img
    var imgUrl = document.getElementById('secImg').src;
    http.ajax({
        url: imgUrl,
        dataType: 'blob',
        success: function (blob, status, xhr) {
            blobToBase64(blob, function (base64) {
                var formData = new FormData();
                // 替换自己的图鉴用户名
                formData.append('username', 'xxxxxx');
                // 替换自己的图鉴密码
                formData.append('password', 'xxxxxx');
                formData.append('typeid', '11');
                formData.append('image', base64.replace('data:image/jpeg;base64,', ''));
                http.ajax({
                    url: 'http://api.ttshitu.com/predict',
                    type: 'POST',
                    data: formData,
                    dataType: 'json',
                    timeout: 0,
                    success: function (response, status, xhr) {
                        let d = response.data;
                        if (d.success) {
                            let {id, result} = d.data;
                            // 替换自己的验证码 img
                            document.getElementById('SecurityCode').value = result;
                            // 替换自己的登录按钮
                            document.getElementById('btnLogin').click();
                        }
                    },
                    error: (xhr, status, error) => {
                        console.log(error);
                    }
                });
            });
        },
        error: (xhr, status, error) => {
            console.log(error);
        }
    });
}
// 调用登录方法
auto_login();

参考文档

相关文章
|
4月前
|
监控 供应链 搜索推荐
电商数据开发实践:深度剖析1688商品详情 API 的技术与应用
在电商数字化转型中,数据获取效率与准确性至关重要。本文介绍了一款高效商品详情API,具备全维度数据采集、价格库存管理、多媒体资源获取等功能,结合实际案例探讨其在电商开发中的应用价值与优势。
|
4月前
|
JSON 算法 API
深度分析小红书城API接口,用Python脚本实现
小红书作为以UGC内容为核心的生活方式平台,其非官方API主要通过移动端抓包解析获得,涵盖内容推荐、搜索、笔记详情、用户信息和互动操作等功能。本文分析了其接口体系、认证机制及请求规范,并提供基于Python的调用框架,涉及签名生成、登录态管理与数据解析。需注意非官方接口存在稳定性与合规风险,使用时应遵守平台协议及法律法规。
|
4月前
|
前端开发 Java API
利用 Spring WebFlux 技术打造高效非阻塞 API 的完整开发方案与实践技巧
本文介绍了如何使用Spring WebFlux构建高效、可扩展的非阻塞API,涵盖响应式编程核心概念、技术方案设计及具体实现示例,适用于高并发场景下的API开发。
408 0
|
4月前
|
JSON API 数据安全/隐私保护
【干货满满】分享微店API接口到手价,用python脚本实现
微店作为知名社交电商平台,其开放平台提供商品查询、订单管理等API接口。本文介绍如何通过微店API获取商品到手价(含优惠、券等),涵盖认证机制、Python实现及关键说明。
|
4月前
|
JSON API 数据安全/隐私保护
【干货满满】分享淘宝API接口到手价,用python脚本实现
淘宝开放平台通过API可获取商品到手价,结合商品详情与联盟接口实现优惠计算。需使用AppKey、AppSecret及会话密钥认证,调用taobao.tbk.item.info.get接口获取最终价格。代码示例展示签名生成与数据解析流程。
|
4月前
|
JSON API 数据安全/隐私保护
深度分析苏宁API接口,用Python脚本实现
苏宁易购开放平台提供覆盖商品、订单、库存、门店等零售全链路的API服务,采用RESTful架构与“AppKey+AppSecret+签名”认证机制,支持线上线下一体化业务处理。本文详解其API特性、认证流程及Python调用实现。
|
4月前
|
自然语言处理 安全 API
深度分析洋码头API接口,用Python脚本实现
洋码头是国内知名跨境电商平台,专注于海外商品直购。本文基于其API的通用设计逻辑,深入解析了认证机制、签名规则及核心接口功能,并提供了Python调用示例,适用于商品与订单管理场景。
|
4月前
|
JSON API 数据格式
深度分析易贝API接口,用Python脚本实现
本文深度解析了eBay开放平台的RESTful API接口体系,涵盖其核心功能、OAuth 2.0认证机制、请求规范及限流策略,并基于Python构建了完整的API调用框架。内容包括商品与订单管理接口的实现逻辑、认证流程、错误处理机制及实战调用示例,适用于跨境电商系统开发与多平台集成。
|
4月前
|
JSON 监控 BI
深度分析亚马逊API接口,用Python脚本实现
本内容深度解析亚马逊SP-API接口体系,涵盖商品、订单、库存等核心功能域,详解LWA认证、AWS签名及Python调用实现,适用于跨境电商系统开发与集成。
|
4月前
|
JSON API 数据格式
深度分析大麦网API接口,用Python脚本实现
大麦网为国内领先演出票务平台,提供演唱会、话剧、体育赛事等票务服务。本文基于抓包分析其非官方接口,并提供Python调用方案,涵盖演出列表查询、详情获取及城市列表获取。需注意非官方接口存在稳定性风险,使用时应遵守平台规则,控制请求频率,防范封禁与法律风险。适用于个人学习、演出信息监控等场景。