提前感谢您的帮助。
我想创建一个使用不同技术进行网页抓取的脚本。这是我的主要脚本,目标是确保它无法更改。
//main//
const main = async (page) => {
const url = 'https://app.proxiesapi.com/login/index.php';
await page.goto(url);
await page.waitForFunction(() => document.readyState === 'complete')
const email = '[email protected]';
await page.evaluate(({ email }) => {
document.querySelector('#myusername').value = email;
}, { email });
const inputFieldValue = await page.evaluate(() => {
return document.querySelector('#myusername').value;
});
console.log({ inputFieldValue });
return page;
};
export { main };
这是我的电子脚本:
import { app, BrowserWindow, session } from 'electron';
import { main } from './script.js';
// create browser /page //
export async function createBrowser() {
await app.whenReady();
const browserWindow = new BrowserWindow({ width: 800, height: 600, show: true });
return browserWindow;
}
async function createTab(browser) {
return browser;
}
// go to url//
async function goto(page, url) {
await page.loadURL(url);
return page;
}
// evaluate electron style//
const evaluate = async (page, func, args) => {
const funcStr = `(${func})(${JSON.stringify(args)})`;
return await page.webContents.executeJavaScript(funcStr);
}
// wait Load //
const waitForFunction = async (page, func) => {
return new Promise((resolve) => {
const intervalId = setInterval(() => {
page.webContents.executeJavaScript(`(${func})()`).then((result) => {
if (result) {
clearInterval(intervalId);
resolve(result);
}
}).catch(console.error);
}, 100);
});
}
async function clear(tab, browser) {
await session.defaultSession.clearStorageData();
tab.close();
await browser.close();
}
// Call function //
(async () => {
const browser = await createBrowser();
let page = await createTab(browser);
page.goto = goto.bind(null, page);
page.waitForFunction = waitForFunction.bind(null, page);
page.evaluate = evaluate.bind(null, page);
page = await main(page);
await clear(page, browser);
})();
它是函数式的,但我不想使用 eval() 或executeJavaScript 之类的东西。相反,我想直接将我的脚本注入到页面中。你知道如何用 Electron 做到这一点吗?
您必须使用
preload.js
脚本。
更新你的main.js
webPreferences: {
preload: path.join(__dirname, 'preload.js'), // Path to preload script
contextIsolation: true,
enableRemoteModule: false
}
添加等待负载
const waitForFunction = async (page, func) => {
return page.webContents.executeJavaScript(`window.electron.waitForFunction(${JSON.stringify(func)})`);
}
据此更新您的通话功能,但尝试像这样使用:
(async () => {
})();
在您的
preload.js
中创建 contextBridge.exposeInMainWorld
,添加 waitForFunction
和设置值并获取值。
那么你就可以避免使用
eval()