[Node.js] puppeteer - 브라우저 제어 사용방법(웹 크롤)
- 테스팅 툴, 웹 크롤러로 활용 (웹 사이트 크롤 , web crawl, crawler )
- 크롬 조종
- Headless Chrome Node.js API
https://github.com/puppeteer/puppeteer - 64k
- v5.2.1, 2020/07
- 설치
npm i puppeteer
- 테스트 파일 작성, test/pup1.js
const puppeteer = require('puppeteer');
const extensionPath = 'C:\\Users\\userID\\AppData\\Local\\Google\\Chrome\\User Data\\Profile 2\\Extensions\\cjpalhdlnbpafiamejdnhcphjbkeiagm\\1.29.2_0';
(async () => {
const browser = await puppeteer.launch(
{
headless: false,
args: [
//크롬 확장 로드
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`
],
devtools: true
});
const page = await browser.newPage();
await page.goto('http://example.com');
//await page.waitFor(3000); //대기
ret = await page.waitForSelector('#word1'); //노드가 나타날때까지 기다림
await page.screenshot({ path: 'example.png' });//사이트 스크린 샷
await browser.close();
})();
- 테스트 실행
node test/pup1.js
//-------------------------------
- 탭 변경
let page = (await browser.pages())[0];//첫 번째 탭
await page.bringToFront(); // 탭 전환
//-------------------------------
- 브라우저의 콘솔 메시지 캡쳐
page.on('console', msg => {
for (let i = 0; i < msg.args().length; ++i)
console.log(`${i}: ${msg.args()[i]}`, msg._text);
});
- page.$eval, page.evaluate 내부의 console.log 메시지 보기
- 브라우저에서 실행되는 개념이므로 , 브라우저에서 확인 하거나, 브라우저의 console.log를 캡쳐
page.on('console', consoleObj => console.log(consoleObj.text()));
//----------------------------------------
- $eval 나 evaluate 함수 안에서 브라우저와 동일하게 자바스크립트를 실행시킬수 있다
page.evaluate( () =>{
console.log(window.name);
});
// $eval 이용
async function pptGetNodeInfo(page, selector, _info) {
let ret = await page.$eval(selector, (node, _info) => {
return node[`${_info}`];//.innerHTML;
}, _info); // 변수 전달
return ret;
}
// evaluate 이용
async function pptGetNodeInfo2(page, selector, _info) {
const node = await page.$(selector);
const ret = await page.evaluate(
(node, _info) => node[`${_info}`]
, node, _info); // 변수 전달
await node.dispose();
return ret;
}
//---------------------------------------------
- 마우스 더블 클릭
async function dblClick(page, sel) {
const node = await page.$(sel);
const fromBox = await node.boundingBox();
const fromX = fromBox.x + 1;// + fromBox.width / 2;
const fromY = fromBox.y + 1;// + fromBox.height / 2;
await page.mouse.move(fromX, fromY, { steps: 10 });
await page.mouse.click(fromX, fromY, { clickCount: 2 });
//await node.click({ clickCount: 2 });//주의! 이 코드는 아래에 노드가 있으면 실패
}