我正在尝试制作一个机器人,它可以获取我的证件,并检查我所在城市美国领事馆的签证面试预约是否可用,但这是我的第一个Javascript应用程序,我像一只无头鸡一样到处乱跑。
首先,联邦调查局特工的免责声明如下:该应用程序是不可扩展的,不会损害服务器,因为它使用我的帐户来检查约会日期。
现在,针对这个问题。这是前面提到的功能:
let checkAvailability = () => {
(async () => {
gSpinner.stop();
console.log(chalk.gray('Opening Chrome headless...'));
let browser = await puppeteer.launch();
let page = await browser.newPage();
let spinner = new CLI.Spinner('Signing in...');
spinner.start();
await page.goto('https://ais.usvisa-info.com/en-ca/niv/users/sign_in');
await page.type('#user_email', config.username);
await page.type('#user_password', config.password);
await page.$eval('#policy_confirmed', check => check.checked = true);
await page.waitForTimeout(3000);
await Promise.all([
page.waitForNavigation(), page.click('input[type=submit]')
]).catch(() => { console.error("Error Occurred.") });
spinner.stop();
console.log(chalk.green('Signed in!'));
console.log(chalk.yellow(`Checking at: ${Date().toLocaleString()}`));
let response = await page.goto(`https://ais.usvisa-info.com/en-ca/niv/schedule/${config.schedule_id}/appointment/days/${locationId}.json?appointments[expedite]=false`);
let json = await response.json();
console.log(json.slice(0, 5));
if (json.length == 0) {
console.log(chalk.red('No appointments!'));
} else if(Date.parse(json[0].date) < alertBefore){
console.log(chalk.green('Early appointment available!!!'));
console.log(chalk.white(json[0].date));
beepbeep(5)
} else {
console.log(chalk.red('No early appointments!'));
}
console.log(chalk.gray('Closing Chrome headless...'));
await browser.close();
let next = new Date();
next.setTime(next.getTime() + interval);
console.log(chalk.gray(`Next checking at: ${next.toLocaleString()}`));
gSpinner.start();
setTimeout(checkAvailability, interval);
})();
}
checkAvailability();
对我来说,这应该是完全合理的,但目前我收到错误消息,即网站在“wait-response.json();”处没有返回有效的json数据。以下是错误代码:
undefined:1
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at HTTPResponse.json (file:///C:/usvisa-appointment-checker/node_modules/puppeteer/lib/esm/puppeteer/common/HTTPResponse.js:164:21)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async file:///C:/usvisa-appointment-checker/check-appointment.js:73:16
我不知道puppeteer库是如何工作的,也不知道如何处理未定义的返回值,或者如何检查网站实际返回的类型o值。有什么想法吗?
以下是完整的代码供参考:
#!/usr/bin/env node
import chalk from 'chalk';
import figlet from 'figlet';
import clear from 'clear';
import CLI from 'clui';
import puppeteer from 'puppeteer';
import fs from 'fs';
import beepbeep from 'beepbeep';
import * as path from 'path';
import {fileURLToPath} from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const config = JSON.parse(fs.readFileSync(`${__dirname}/.config.json`));
let locationId = '';
switch(config.location) {
case 'vancouver':
locationId = '95';
break;
case 'calgary':
locationId = '89';
break;
case 'ottawa':
locationId = '92';
break;
case 'toronto':
locationId = '94';
case 'montreal':
locationId = '91';
}
clear();
console.log(
chalk.yellow(
figlet.textSync('VISA Appointment')
)
);
const interval = 600000;
const alertBefore = new Date(config.alert_for_appointment_before);
let gSpinner = new CLI.Spinner('Waiting for the next run...');
let checkAvailability = () => {
(async () => {
gSpinner.stop();
console.log(chalk.gray('Opening Chrome headless...'));
let browser = await puppeteer.launch();
let page = await browser.newPage();
let spinner = new CLI.Spinner('Signing in...');
spinner.start();
await page.goto('https://ais.usvisa-info.com/en-ca/niv/users/sign_in');
await page.type('#user_email', config.username);
await page.type('#user_password', config.password);
await page.$eval('#policy_confirmed', check => check.checked = true);
await page.waitForTimeout(3000);
await Promise.all([
page.waitForNavigation(), page.click('input[type=submit]')
]).catch(() => { console.error("Error Occurred.") });
spinner.stop();
console.log(chalk.green('Signed in!'));
console.log(chalk.yellow(`Checking at: ${Date().toLocaleString()}`));
let response = await page.goto(`https://ais.usvisa-info.com/en-ca/niv/schedule/${config.schedule_id}/appointment/days/${locationId}.json?appointments[expedite]=false`);
let json = await response.json();
console.log(json.slice(0, 5));
if (json.length == 0) {
console.log(chalk.red('No appointments!'));
} else if(Date.parse(json[0].date) < alertBefore){
console.log(chalk.green('Early appointment available!!!'));
console.log(chalk.white(json[0].date));
beepbeep(5)
} else {
console.log(chalk.red('No early appointments!'));
}
console.log(chalk.gray('Closing Chrome headless...'));
await browser.close();
let next = new Date();
next.setTime(next.getTime() + interval);
console.log(chalk.gray(`Next checking at: ${next.toLocaleString()}`));
gSpinner.start();
setTimeout(checkAvailability, interval);
})();
}
checkAvailability();
回购金额:
https://github.com/patrickyin/usvisa-appointment-checker
尝试了一些基本的错误处理,但再次不知道我在做什么。使用try-and-catch只是给了我另一个类似的错误代码,因为我不知道网站返回的是什么类型的数据。