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
설치가 완료 되었다면 개발자도구에서 selectorHub를 클릭해 보자.
검색창에
//span[text()="쇼핑"]/ancestor::a
여기서 문법은 이 사이트에서 확인해 보자
https://www.guru99.com/xpath-selenium.html
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 |
---|