英文:
Puppeteer failing to click a tag with same id second time after content changes
问题
以下是您提供的代码的翻译部分:
import tesseract from 'node-tesseract-ocr';
import Puppeteer from 'puppeteer';
const config = {
lang: 'eng', // 默认值
oem: 3,
psm: 13,
};
export class AutomationController {
public async CreateProfile(data: any) {
try {
const _data = {
nationality: 'BRA',
id: '0508228690083',
title: 'Mr',
firstName: 'Shaun',
middleName: 'Maxwell',
surname: 'Smith',
dob: '15062001',
gender: 'M',
email: 'shaun@gmail.com',
countryCode: '+27',
mobileNumber: '0832567890',
};
const browser = await Puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto(
'https://self-service.wits.ac.za/psc/csprodonl/UW_SELF_SERVICE/SA/c/VC_OA_LOGIN_MENU.VC_OA_LOGIN_FL.GBL',
{ waitUntil: 'networkidle2', timeout: 0 }
);
// 点击创建临时ID按钮
await page.waitForSelector('#VC_OA_LOGIN_WRK_REGISTER');
await page.click('#VC_OA_LOGIN_WRK_REGISTER');
// 国籍字段
await page.waitForSelector('#VC_OA_LOGIN_WRK_COUNTRY');
// 输入ID号码
await page.waitForSelector('#VC_OA_LOGIN_WRK_NATIONAL_ID');
const idInput = await page.$('#VC_OA_LOGIN_WRK_NATIONAL_ID');
await idInput?.type(_data.id);
// 名字前缀字段
await page.waitForSelector('#VC_OA_LOGIN_WRK_NAME_PREFIX');
await page.select(
'select[id="VC_OA_LOGIN_WRK_NAME_PREFIX"]',
_data.title
);
// 名字字段
await page.waitForSelector(
'#win0divVC_OA_LOGIN_WRK_FIRST_NAMEctrl > #VC_OA_LOGIN_WRK_FIRST_NAME'
);
const firstNameInput = await page.$('#VC_OA_LOGIN_WRK_FIRST_NAME');
await firstNameInput?.type(_data.firstName);
// 中间名字段
await page.waitForSelector('#VC_OA_LOGIN_WRK_MIDDLE_NAME');
const middleNameInput = await page.$('#VC_OA_LOGIN_WRK_MIDDLE_NAME');
await middleNameInput?.type(_data.middleName);
// 姓氏字段
await page.waitForSelector('#VC_OA_LOGIN_WRK_LAST_NAME');
const surnameInput = await page.$('#VC_OA_LOGIN_WRK_LAST_NAME');
await surnameInput?.type(_data.surname);
// 性别字段
await page.waitForSelector('#VC_OA_LOGIN_WRK_SEX');
await page.select('select[id="VC_OA_LOGIN_WRK_SEX"]', _data.gender);
// 电子邮件字段
await page.waitForSelector(
'#win0divVC_OA_LOGIN_WRK_EMAIL_ADDRctrl > #VC_OA_LOGIN_WRK_EMAIL_ADDR'
);
const emailInput = await page.$(
'#win0divVC_OA_LOGIN_WRK_EMAIL_ADDRctrl > #VC_OA_LOGIN_WRK_EMAIL_ADDR'
);
await emailInput?.type(_data.email);
// 手机号码字段
await page.waitForSelector('#VC_OA_LOGIN_WRK_VC_PHONE_CELL_SS');
const mobileInput = await page.$('#VC_OA_LOGIN_WRK_VC_PHONE_CELL_SS');
await mobileInput?.type(_data.mobileNumber);
await page.waitForSelector(
'#win0divVC_SEC_WRK_HTML_AREA_02 > div > div > img'
);
// 绕过安全检查
const imgs = await page.$$eval(
'#win0divVC_SEC_WRK_HTML_AREA_02 > div > div > img',
(imgs) => imgs.map((img) => img.getAttribute('src'))
);
const securityPassword = this.getCharacterAfterSecondUnderscore(imgs);
await page.waitForSelector('#VC_OA_LOGIN_WRK_VC_SEC_CODE');
const securityField = await page.$('#VC_OA_LOGIN_WRK_VC_SEC_CODE');
await securityField?.type(securityPassword);
// 点击继续按钮
await page.waitForSelector('#VC_OA_LOGIN_WRK_CONTINUE_PB');
const continueBtn = await page.$('#VC_OA_LOGIN_WRK_CONTINUE_PB');
await continueBtn.click();
// 延迟等待
await this.delay(5000);
// 确认详细信息按钮
const confirmBtn = await page.$('#VC_OA_LOGIN_WRK_CONTINUE_PB');
await confirmBtn.click();
console.log(`Automation.controller - 136`, 'DONE');
await this.delay(4000);
} catch (error) {
console.log(`Automation.controller - 137`, error);
}
}
private delay(time) {
return new Promise(function (resolve) {
setTimeout(resolve, time);
});
}
private getCharacterAfterSecondUnderscore(strings: string[]): string {
const results: string[] = [];
for (const string of strings) {
const splittedString = string.split('_');
results.push(splittedString[2]);
}
return results.join('');
}
}
请注意,这只是您提供的代码的翻译部分,不包括代码的功能或解释。如果您需要更多帮助或有其他问题,请随时提出。
英文:
Working on Puppeteer to learn,so I am trying to form fill this site
What script does
- Goes to link above
- Click 'Create Temporary ID'
- Fill form
- Click continue
- Content changes
- Click continue again (Which is the same button with same ID value as the first 'Continue' button
ISSUE
- When I click on the button 'Continue' button for second time which is the same ID as the one that worked first it fails
SCRIPT
import tesseract from 'node-tesseract-ocr';
import Puppeteer from 'puppeteer';
const config = {
lang: 'eng', // default
oem: 3,
psm: 13,
};
export class AutomationController {
public async CreateProfile(data: any) {
try {
const _data = {
nationality: 'BRA',
id: '0508228690083',
title: 'Mr',
firstName: 'Shaun',
middleName: 'Maxwell',
surname: 'Smith',
dob: '15062001',
gender: 'M',
email: 'shaun@gmail.com',
countryCode: '+27',
mobileNumber: '0832567890',
};
const browser = await Puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto(
'https://self-service.wits.ac.za/psc/csprodonl/UW_SELF_SERVICE/SA/c/VC_OA_LOGIN_MENU.VC_OA_LOGIN_FL.GBL',
{ waitUntil: 'networkidle2', timeout: 0 }
);
// Click create temp id button
await page.waitForSelector('#VC_OA_LOGIN_WRK_REGISTER');
await page.click('#VC_OA_LOGIN_WRK_REGISTER');
// Nationality field
await page.waitForSelector('#VC_OA_LOGIN_WRK_COUNTRY');
// await page.select('select[id="VC_OA_LOGIN_WRK_COUNTRY"]', 'AUS');
// ID number field
await page.waitForSelector('#VC_OA_LOGIN_WRK_NATIONAL_ID');
const idInput = await page.$('#VC_OA_LOGIN_WRK_NATIONAL_ID');
await idInput?.type(_data.id);
await this.delay(4000);
// Name Title field
await page.waitForSelector('#VC_OA_LOGIN_WRK_NAME_PREFIX');
await page.select(
'select[id="VC_OA_LOGIN_WRK_NAME_PREFIX"]',
_data.title
);
await this.delay(4000);
// First name field
await page.waitForSelector(
'#win0divVC_OA_LOGIN_WRK_FIRST_NAMEctrl > #VC_OA_LOGIN_WRK_FIRST_NAME'
); // VC_OA_LOGIN_WRK_FIRST_NAME
const firstNameInput = await page.$('#VC_OA_LOGIN_WRK_FIRST_NAME');
await firstNameInput?.type(_data.firstName);
await this.delay(4000);
// Middle name field
await page.waitForSelector('#VC_OA_LOGIN_WRK_MIDDLE_NAME');
const middleNameInput = await page.$('#VC_OA_LOGIN_WRK_MIDDLE_NAME');
await middleNameInput?.type(_data.middleName);
await this.delay(4000);
// Surname field
await page.waitForSelector('#VC_OA_LOGIN_WRK_LAST_NAME');
const surnameInput = await page.$('#VC_OA_LOGIN_WRK_LAST_NAME');
await surnameInput?.type(_data.surname);
await this.delay(4000);
// Gender field
await page.waitForSelector('#VC_OA_LOGIN_WRK_SEX');
await page.select('select[id="VC_OA_LOGIN_WRK_SEX"]', _data.gender);
await this.delay(4000);
// Email field
await page.waitForSelector(
'#win0divVC_OA_LOGIN_WRK_EMAIL_ADDRctrl > #VC_OA_LOGIN_WRK_EMAIL_ADDR'
);
const emailInput = await page.$(
'#win0divVC_OA_LOGIN_WRK_EMAIL_ADDRctrl > #VC_OA_LOGIN_WRK_EMAIL_ADDR'
);
await emailInput?.type(_data.email);
await this.delay(4000);
// Mobile number
await page.waitForSelector('#VC_OA_LOGIN_WRK_VC_PHONE_CELL_SS');
const mobileInput = await page.$('#VC_OA_LOGIN_WRK_VC_PHONE_CELL_SS');
await mobileInput?.type(_data.mobileNumber);
await this.delay(4000);
await page.waitForSelector(
'#win0divVC_SEC_WRK_HTML_AREA_02 > div > div > img'
);
// Bypass security check
const imgs = await page.$$eval(
'#win0divVC_SEC_WRK_HTML_AREA_02 > div > div > img',
(imgs) => imgs.map((img) => img.getAttribute('src'))
);
const securityPassword = this.getCharacterAfterSecondUnderscore(imgs);
await page.waitForSelector('#VC_OA_LOGIN_WRK_VC_SEC_CODE');
const securityField = await page.$('#VC_OA_LOGIN_WRK_VC_SEC_CODE');
await securityField?.type(securityPassword);
await this.delay(4000);
// Continue button
await page.waitForSelector('#VC_OA_LOGIN_WRK_CONTINUE_PB');
const continueBtn = await page.$('#VC_OA_LOGIN_WRK_CONTINUE_PB');
await continueBtn.click();
this.delay(5000);
// TODO - HANDLE IF SECURITY CHECK FAILED
//THIS THE BUTTON THAT FAILS TO CLICK SECOND TIME
// CONFIRM Details button
const confirmBtn = await page.$('#VC_OA_LOGIN_WRK_CONTINUE_PB');
await confirmBtn.click();
console.log(`Automation.controller - 136`, 'DONE');
await this.delay(4000);
} catch (error) {
console.log(`Automation.controller - 137`, error);
}
}
private delay(time) {
return new Promise(function (resolve) {
setTimeout(resolve, time);
});
}
private getCharacterAfterSecondUnderscore(strings: string[]): string {
const results: string[] = [];
for (const string of strings) {
const splittedString = string.split('_');
results.push(splittedString[2]);
}
return results.join('');
}
}
答案1
得分: 3
我在我的机器上尝试了这个,并且解决你的问题非常简单,你只是忘记在this.delay(5000);
行的开头添加await
关键字:
...
// 等待继续按钮
await page.waitForSelector('#VC_OA_LOGIN_WRK_CONTINUE_PB');
const continueBtn = await page.$('#VC_OA_LOGIN_WRK_CONTINUE_PB');
await continueBtn.click();
await this.delay(5000); // 你忘记在这里添加 await
// TODO - 处理如果安全检查失败的情况
// 这是第二次点击失败的按钮
// 确认详情按钮
const confirmBtn = await page.$('#VC_OA_LOGIN_WRK_CONTINUE_PB');
await confirmBtn.click();
...
英文:
I tried this on my machine, and the answer to your problem is very simple, you simply forgot to add await
keyword on the beginning of this.delay(5000);
line:
...
// Continue button
await page.waitForSelector('#VC_OA_LOGIN_WRK_CONTINUE_PB');
const continueBtn = await page.$('#VC_OA_LOGIN_WRK_CONTINUE_PB');
await continueBtn.click();
await this.delay(5000); // YOU FORGOT TO ADD await HERE
// TODO - HANDLE IF SECURITY CHECK FAILED
//THIS THE BUTTON THAT FAILS TO CLICK SECOND TIME
// CONFIRM Details button
const confirmBtn = await page.$('#VC_OA_LOGIN_WRK_CONTINUE_PB');
await confirmBtn.click();
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论