Puppeteer에서 여러 iframe을 구문 분석하려고 할 때 막힌 것
환경
개요
Page#frames
를 사용합니다.코드
test.tsimport {launch} from 'puppeteer';
(async () => {
const browser = await launch();
const page = await browser.newPage();
try {
await page.goto('file:///tmp/test.html');
let frames = page.frames();
// frames[0]は今いるページを指しているため、ページ内のiframeを探す場合インデックスは1以降になる
for (let i = 1; i < frames.length; i++) {
const frame = frames[i];
console.log(await frame.evaluate(content => content.innerHTML, await frame.$('p')));
}
} catch (e) {
console.error(e);
}
await page.close();
await browser.close();
})();
/tmp/test.html<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<iframe src="inner-frame.html"></iframe>
<iframe src="secondary-frame.html"></iframe>
</body>
</html>
/tmp/inner-frame.html<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>InnerFrame</title>
</head>
<body>
<p>Inner Frame!</p>
</body>
</html>
/tmp/secondary-frame.html<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SecondaryFrame</title>
</head>
<body>
<p>Secondary Frame!</p>
</body>
</html>
실행 결과
$ node test.js
Inner Frame!
Secondary Frame!
(뱀족) 시행착오의 흔적
일의 발단
test.tsimport {launch} from 'puppeteer';
(async () => {
const browser = await launch();
const page = await browser.newPage();
try {
await page.goto('file:///tmp/test.html');
const frames = await page.$$('iframe');
for (let i = 0; i < frames.length; i++) {
const url = await page.evaluate(content => content.src, frames[i]);
await page.goto(url);
console.log(await page.evaluate(content => content.innerHTML, await page.$('p')));
}
} catch (e) {
console.error(e);
}
await page.close();
await browser.close();
})();
실행 결과
$ node test.js
Inner Frame!
Error: JSHandles can be evaluated only in the context they were created!
at ExecutionContext.convertArgument (~~~/node_modules/puppeteer/lib/ExecutionContext.js:95:17)
at Array.map (<anonymous>)
at ExecutionContext.evaluateHandle (~~~/node_modules/puppeteer/lib/ExecutionContext.js:70:23)
at ExecutionContext.evaluate (~~~/node_modules/puppeteer/lib/ExecutionContext.js:46:31)
at Frame.evaluate (~~~/node_modules/puppeteer/lib/FrameManager.js:299:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
왠지 에러 나오고 있다…
제1차 개수
test.tsimport {launch} from 'puppeteer';
(async () => {
const browser = await launch();
const page = await browser.newPage();
try {
await page.goto('file:///tmp/test.html');
const frames = await page.$$('iframe');
const urls = [];
for (let i = 0; i < frames.length; i++) {
urls.push(await page.evaluate(content => content.src, frames[i]));
}
for (let i = 0; i < urls.length; i++) {
await page.goto(urls[i]);
console.log(await page.evaluate(content => content.innerHTML, await page.$('p')));
}
} catch (e) {
console.error(e);
}
await page.close();
await browser.close();
})();
실행 결과
$ node test.js
Inner Frame!
Secondary Frame!
< 루프 2회시키는 것도…
그래서 거부
import {launch} from 'puppeteer';
(async () => {
const browser = await launch();
const page = await browser.newPage();
try {
await page.goto('file:///tmp/test.html');
let frames = page.frames();
// frames[0]は今いるページを指しているため、ページ内のiframeを探す場合インデックスは1以降になる
for (let i = 1; i < frames.length; i++) {
const frame = frames[i];
console.log(await frame.evaluate(content => content.innerHTML, await frame.$('p')));
}
} catch (e) {
console.error(e);
}
await page.close();
await browser.close();
})();
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<iframe src="inner-frame.html"></iframe>
<iframe src="secondary-frame.html"></iframe>
</body>
</html>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>InnerFrame</title>
</head>
<body>
<p>Inner Frame!</p>
</body>
</html>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SecondaryFrame</title>
</head>
<body>
<p>Secondary Frame!</p>
</body>
</html>
$ node test.js
Inner Frame!
Secondary Frame!
일의 발단
test.ts
import {launch} from 'puppeteer';
(async () => {
const browser = await launch();
const page = await browser.newPage();
try {
await page.goto('file:///tmp/test.html');
const frames = await page.$$('iframe');
for (let i = 0; i < frames.length; i++) {
const url = await page.evaluate(content => content.src, frames[i]);
await page.goto(url);
console.log(await page.evaluate(content => content.innerHTML, await page.$('p')));
}
} catch (e) {
console.error(e);
}
await page.close();
await browser.close();
})();
실행 결과
$ node test.js
Inner Frame!
Error: JSHandles can be evaluated only in the context they were created!
at ExecutionContext.convertArgument (~~~/node_modules/puppeteer/lib/ExecutionContext.js:95:17)
at Array.map (<anonymous>)
at ExecutionContext.evaluateHandle (~~~/node_modules/puppeteer/lib/ExecutionContext.js:70:23)
at ExecutionContext.evaluate (~~~/node_modules/puppeteer/lib/ExecutionContext.js:46:31)
at Frame.evaluate (~~~/node_modules/puppeteer/lib/FrameManager.js:299:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
왠지 에러 나오고 있다…
제1차 개수
test.ts
import {launch} from 'puppeteer';
(async () => {
const browser = await launch();
const page = await browser.newPage();
try {
await page.goto('file:///tmp/test.html');
const frames = await page.$$('iframe');
const urls = [];
for (let i = 0; i < frames.length; i++) {
urls.push(await page.evaluate(content => content.src, frames[i]));
}
for (let i = 0; i < urls.length; i++) {
await page.goto(urls[i]);
console.log(await page.evaluate(content => content.innerHTML, await page.$('p')));
}
} catch (e) {
console.error(e);
}
await page.close();
await browser.close();
})();
실행 결과
$ node test.js
Inner Frame!
Secondary Frame!
< 루프 2회시키는 것도…
그래서 거부
Reference
이 문제에 관하여(Puppeteer에서 여러 iframe을 구문 분석하려고 할 때 막힌 것), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/gkasse/items/281e510f60902d8606d7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)