Node JS/puppeteer

puppeteer (기본기)

seongjin08 2022. 7. 4. 21:36

puppeteer 란?

구글에서 만든 웹브라우져 자동화 라이브러리

구글에서 만들었기 때문에 크롬 혹은 크로미엄 에서만 작동 하다.

 

nodejs 가 깔린 상태에서

먼저 빈폴더를 생성 후 

npm init

of 

yarn init

 

npm install puppeteer

or

yarn add puppeteer

 

파일을 하나 생성하자

나는 server.js 로 만들겠다

잘 불러왔는지 확인하기 위해 함수를 만들고 실행 시켜보자 

const puppeteer = require('puppeteer');


( async()=>{
console.log('starting...');
console.log('puppeteer',puppeteer);
})()

$ node server.js

하면 잘 실행 된걸 알 수있다. 여기서 .js 부분은 생략해도 무방하다.

 

 

파라미터로 headless 를 false 로 주어야 하나다.

디폴드 값이 true 여서 그냥 실행시키면 우리 눈에 브라우져가 보이지 않는다.

args 에는 디폴드 사이즈가 작아서  "--window-size-1920,1080" 로 큰사이즈로 만들어 보자.

자동화 프로그램이라 빨리 진행됨으로 slowMo:39

 

자바스크립트는 비동기 이기때문에 콜백함수를 상용하든 async await 을 사용하여 동기로 만들어 주어야 한다.

const puppeteer = require('puppeteer');


( async()=>{
console.log('starting...');
console.log('puppeteer',puppeteer);

const browser = await puppeteer.launch({
    headless:false,
    args:['--window-size-1920,1080'],
    slowMo:30,
})

const page = await browser.newPage();  //크롬에서 탭을 생성

await Promise.all([
    page.goto("http://www.naver.com"),  //생성한 탭에 naver 페이지 열기
    page.waitForNavigation()  //위 페이지가 로드 될때까지 기다려라. 위에랑 셋트
])

await page.waitForTimeout(3000);  // 3초간 기다려라

await page.close();  // 페이지를 닫아라
})()

지금까지 작성한 코드를 실행시키면 이렇게 작동 할 것이다.

여기서 이상한 점을 느낄 것이다. 네이버의 사이즈가 작게나오는 걸 수정 해 보자.

 

page 선언 및에 이걸 쎃주면 된다.

await page.setViewport({
    width:1680,
    height:1050
})

맥북에어는 최대 해상도가 1680 x 1050 이여서 나는 이렇게 했지만 

보통 1920 x 1080  으로 하면 풀 사이즈 일 것이다.

 

이제 네이버를 불러오고 쇼핑을 클릭하기 위해서는 어떻게 할까?

개발자 도구를 켜서 (F12)  

copy 에서 copy selector 를 클릭하면
#NM_FAVORITE > div.group_nav > ul.list_nav.type_fix > li:nth-child(5) > a

이렇게 값을 가져 올 수 있다. 

 

하지만 이후 쇼핑 태그에 위치가 바뀌게 되면 그때마다 변경을 해주어야 할 것이다.

그래서 글자를 찾아서 위치를 가져오는 방법을 하기위해 

SelectorHub 를 설치해 보자.

 

https://chrome.google.com/webstore/detail/selectorshub/ndgimibanhlabgdgjcpbbndiehljcpfh/related

 

SelectorsHub

xPath plugin to auto generate, write and verify xpath & cssSelector.

chrome.google.com

 

설치가 완료 되었다면 개발자도구에서 selectorHub를 클릭해 보자.

검색창에 

//span[text()="쇼핑"]/ancestor::a

여기서 문법은 이 사이트에서 확인해 보자

https://www.guru99.com/xpath-selenium.html

 

XPath in Selenium: How to Find & Write Text, Contains, OR, AND

In this tutorial, you will learn XPath definition, Types, Basic XPath, Contains, OR & AND, Starts-with Function, XPath Axes Methods, and more.

www.guru99.com

 

const puppeteer = require('puppeteer');


( async()=>{
console.log('starting...');
// console.log('puppeteer',puppeteer);

const browser = await puppeteer.launch({
    headless:false,
    args:['--window-size-1920,1080'],
    slowMo:30,
})

const page = await browser.newPage();  //크롬에서 탭을 생성

await page.setViewport({
    width:1580,
    height:1050
})
await Promise.all([
    page.goto("http://www.naver.com"),  //생성한 탭에 naver 페이지 열기
    page.waitForNavigation()  //위 페이지가 로드 될때까지 기다려라. 위에랑 셋트
])

let target = "//span[text()='쇼핑']/ancestor::a";
// await page.waitForTimeout(3000) //이 함수를 쓰게 되면 무조건 3초를 기다린 후에 다음이 실행된다.
await page.waitForXPath(target)  //로딩되고 target이 잡힌두 넘어간다. 디폴트로 최대 30초 가되어 있다. 변경도 가능. 
let s = await page.$x(target) //같은게 여러게 있을 수 있으므로 배열로 값을 반환하게 된다.
s = s[0]


await Promise.all([
    await s.click(),  //클릭 이벤트 추가 
    page.waitForNavigation()
])

await page.waitForTimeout(3000);  // 3초간 기다려라

// await page.close();  // 페이지를 닫아라
})()

 

현재까지의 코드를 실행하게 되면 웹페이지가 켜지고 네이버 접속 후 쇼핑을 클리하여 쇼핑페이지로 넘어가게 된다.

 

이번에는 쇼핑 페이지에서 리스트 값을 가져와 보자

 

이 카테고리에 값을 가져와 보자.

아까와 같이 selectHub 을 이용해 target 을 잡고 

배열로 반환되니 반복문을 통해 값을 console 에 찍어보자.

target = "//ul[@id='categoryListPage1']/li/button";
await page.waitForXPath(target) 
 s = await page.$x(target) 

 for( item of s ){
    const value = await item.evaluate(el => el.textContent);
    console.log('value',value.trim()); //공백이 있으므로 trim 을 써서 공백을 없앤다.
 }

이렇게 찍히는 것을 확인 할 수있다.

 

이번에는 검색창에서 검색을 해보자.

const puppeteer = require('puppeteer');


(async () => {
    console.log('starting...');
    // console.log('puppeteer',puppeteer);

    const browser = await puppeteer.launch({
        headless: false,
        args: ['--window-size-1920,1080'],
        slowMo: 30,
    })

    const page = await browser.newPage();  //크롬에서 탭을 생성

    await page.setViewport({
        width: 1580,
        height: 1050
    })
    await Promise.all([
        page.goto("http://www.naver.com"),  //생성한 탭에 naver 페이지 열기
        page.waitForNavigation()  //위 페이지가 로드 될때까지 기다려라. 위에랑 셋트
    ])

    let target = "//span[text()='쇼핑']/ancestor::a";
    // await page.waitForTimeout(3000) //이 함수를 쓰게 되면 무조건 3초를 기다린 후에 다음이 실행된다.
    await page.waitForXPath(target)  //로딩되고 target이 잡힌두 넘어간다. 디폴트로 최대 30초 가되어 있다. 변경도 가능. 
    let s = await page.$x(target) //같은게 여러게 있을 수 있으므로 배열로 값을 반환하게 된다.
    s = s[0]


    await Promise.all([
        await s.click(),  //클릭 이벤트 추가 
        page.waitForNavigation()
    ])

    target = "//ul[@id='categoryListPage1']/li/button";
    await page.waitForXPath(target)
    s = await page.$x(target)

    for (item of s) {
        const value = await item.evaluate(el => el.textContent);
        console.log('value', value.trim()); //공백이 있으므로 trim 을 써서 공백을 없앤다.
    }

    target = "//input[@title='검색어 입력']";
    await page.waitForXPath(target)
    s = await page.$x(target)
    s = s[0]
    await s.type('양말')

    target = "//button[@class='_searchInput_button_search_1n1aw']";
    await page.waitForXPath(target)
    s = await page.$x(target)
    s = s[0]
    await s.click()


    await page.waitForTimeout(3000);  // 3초간 기다려라

    await page.close();  // 페이지를 닫아라
})()

 

이렇게 puppeteer 에서 가장 기본적인 부분을 해봤다...

 

'Node JS > puppeteer' 카테고리의 다른 글

[PUPPETEER] 병렬로 처리하기  (0) 2022.07.30