前期准备
前往OCR文字识别_免费试用_图片转文字-百度AI开放平台 (baidu.com),申请文字识别并创建应用,虽然标准版可以调用的次数很多,但还是建议申请高精度版,我试了下普通版本识别准确度不太高
安装依赖
yarn add puppeteer
yarn add baidu-aip-sdk
yarn add download
//or npm
npm install puppeteer
npm install baidu-aip-sdk
npm install download
新建AipOcrClient
AipOcrClient是Optical Character Recognition的node客户端,为使用Optical Character Recognition的开发人员提供了一系列的交互方法。
用户可以参考如下代码新建一个AipOcrClient:
var AipOcrClient = require("baidu-aip-sdk").ocr;
// 设置APPID/AK/SK
var APP_ID = "你的 App ID";
var API_KEY = "你的 Api Key";
var SECRET_KEY = "你的 Secret Key";
// 新建一个对象,建议只保存一个对象调用服务接口
var client = new AipOcrClient(APP_ID, API_KEY, SECRET_KEY);
通用文字识别
用户向服务请求识别某张图中的所有文字。
var fs = require('fs');
var image = fs.readFileSync("assets/example.jpg").toString("base64");
// 调用通用文字识别, 图片参数为本地图片
client.generalBasic(image).then(function(result) {
console.log(JSON.stringify(result));
}).catch(function(err) {
// 如果发生网络错误
console.log(err);
});
// 如果有可选参数
var options = {};
options["language_type"] = "CHN_ENG";
options["detect_direction"] = "true";
options["detect_language"] = "true";
options["probability"] = "true";
// 带参数调用通用文字识别, 图片参数为本地图片
client.generalBasic(image, options).then(function(result) {
console.log(JSON.stringify(result));
}).catch(function(err) {
// 如果发生网络错误
console.log(err);
});;
var url = "https//www.x.com/sample.jpg";
// 调用通用文字识别, 图片参数为远程url图片
client.generalBasicUrl(url).then(function(result) {
console.log(JSON.stringify(result));
}).catch(function(err) {
// 如果发生网络错误
console.log(err);
});
// 如果有可选参数
var options = {};
options["language_type"] = "CHN_ENG";
options["detect_direction"] = "true";
options["detect_language"] = "true";
options["probability"] = "true";
// 带参数调用通用文字识别, 图片参数为远程url图片
client.generalBasicUrl(url, options).then(function(result) {
console.log(JSON.stringify(result));
}).catch(function(err) {
// 如果发生网络错误
console.log(err);
});;
通用文字识别 返回示例
{
"log_id": 2471272194,
"words_result_num": 2,
"words_result":
[
{"words": " TSINGTAO"},
{"words": "青島睥酒"}
]
}
通用文字识别(高精度版)
用户向服务请求识别某张图中的所有文字,相对于通用文字识别该产品精度更高,但是识别耗时会稍长。
var fs = require('fs');
var image = fs.readFileSync("assets/example.jpg").toString("base64");
// 调用通用文字识别(高精度版)
client.accurateBasic(image).then(function(result) {
console.log(JSON.stringify(result));
}).catch(function(err) {
// 如果发生网络错误
console.log(err);
});
// 如果有可选参数
var options = {};
options["detect_direction"] = "true";
options["probability"] = "true";
// 带参数调用通用文字识别(高精度版)
client.accurateBasic(image, options).then(function(result) {
console.log(JSON.stringify(result));
}).catch(function(err) {
// 如果发生网络错误
console.log(err);
});;
使用puppeteer开始模拟签到过程
分析皇后的签到按钮,点击后弹出一个iframe,iframe地址为plugin_sign-in.php
,因此实现的思路就是先打开浏览器把cookie先导入浏览器,访问这个地址即可。
直接开干
let opencdSign = async() => {
let options = {
args: [
//是否使用代理,如果使用代理下面2行取消注释,并填写你自己的代理地址
// '--proxy-server=127.0.0.1:10809',
// '--proxy-bypass-list=<-loopback>',
'--lang=en-US'
],
}
let browser = await puppeteer.launch(options);
const page = await browser.newPage();
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1,
});
let cookieString = `填写你的皇后cookie`
const addCookies = async(cookies_str, page, domain) => {
let cookies = cookies_str.split(';').map(
pair => {
let name = pair.trim().slice(0, pair.trim().indexOf('='));
let value = pair.trim().slice(pair.trim().indexOf('=') + 1);
return { name, value, domain }
});
await Promise.all(cookies.map(pair => {
// console.log(pair);
return page.setCookie(pair)
}))
};
await addCookies(cookieString, page, '皇后地址,不带https://')
await page.goto('https://皇后地址/plugin_sign-in.php');
let image = await page.$eval('#frmSignin > table > tbody > tr > td > img', el => el.src)
console.log(image)
// 调用通用文字识别, 图片参数为网络URL
// client.generalBasicUr(image).then(async result => { //普通版
// 坑爹的高精度不能直接使用网络图片,只能先下载下来
let headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
}
const filePath = `${__dirname}/images`
await download(imageUrl, filePath, {
filename: 'orc.png',
headers,
}).then(() => {
console.log(`Download Completed`)
let image = fs.readFileSync(`${__dirname}/images/orc.png`).toString("base64");
client.accurateBasic(image).then(async result => { //高精度版
let imageOrc = JSON.stringify(result.words_result[0].words).replace(/[^0-9a-zA-z]/g,"")
console.log(imageOrc)
await page.focus('#imagestring')
await page.keyboard.sendCharacter(imageOrc)
await page.click('#ok')
// await page.screenshot({ path: `${new Date().getTime()}opencd.png` });
let signResult = await page.$eval('html', el => JSON.parse(el.innerText))
console.log(signResult)
let signinfo
if (signResult.state == 'success') {
signinfo = `签到成功,签到天数:${signResult.signindays},获得:${signResult.integral}`
} else if (signResult.state == 'false' && signResult.msg) {
signinfo = `${signResult.msg},尝试重新签到`
opencdSign()
} else {
signinfo = `已经签到`
}
await browser.close();
console.log(signinfo)
}).catch(function(err) {
// 如果发生网络错误
console.log(err);
});
})
}
使用node-schedule
实现定时签到
封装下方法
const schedule = require('node-schedule')
// date 参数
// 其他规则见 https://www.npmjs.com/package/node-schedule
// 规则参数讲解, 规则类似 Linux 下的 crontab ('*'代表通配符)
//
// * * * * * *
// ┬ ┬ ┬ ┬ ┬ ┬
// │ │ │ │ │ |
// │ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
// │ │ │ │ └───── month (1 - 12)
// │ │ │ └────────── day of month (1 - 31)
// │ │ └─────────────── hour (0 - 23)
// │ └──────────────────── minute (0 - 59)
// └───────────────────────── second (0 - 59, OPTIONAL)
// 1. 按固定时间触发
//
// 每分钟的第30秒触发: '30 * * * * *'
//
// 每小时的1分30秒触发 :'30 1 * * * *'
//
// 每天的凌晨1点1分30秒触发 :'30 1 1 * * *'
//
// 每月的1日1点1分30秒触发 :'30 1 1 1 * *'
//
// 每周1的1点1分30秒触发 :'30 1 1 * * 1'
// 2. 按时间差触发 (日/月/周同理)
//
// 每30分钟触发一次: '0 */30 * * * *'
//
// 每6小时触发一次: '0 0 */6 * * *'
function setSchedule(date, callback) {
schedule.scheduleJob({tz: 'Asia/Shanghai', rule: date}, callback)
}
module.exports = {
setSchedule
}
引入并调用
const schedule = require('./schedule/index');
schedule.setSchedule('0 0 * * * *', opencdSign())
写的比较混乱,完整代码有空了会优化下发布至github