이전 포스팅 웹 크롤링 로그인 로그아웃에 대하여
로그인과 로그아웃에 대하여 알아보았습니다
코드를 함수형으로 만들어서 이전 코드보다 간결하게 만들어 보았지요
그리고 웹 크롤링에서는 무엇보다
태그를 찾는것 이 중요 하여 같이 알아보았습니다
좀 더 상세히 알고 싶으시다면 아래의 링크를 클릭하시길 바랍니다
2022.08.29 - [IT_Web/Nodejs] - 웹 크롤링 로그인, 로그아웃 그리고 waitForResponse 응답대기 활용하기 및 태그찾기, 태그 값 할당
웹 크롤링 로그인, 로그아웃 그리고 waitForResponse 응답대기 활용하기 및 태그찾기, 태그 값 할당
이전 포스팅에서 웹 크롤링 인피니트 스크롤링이 무엇인가 알아보았으며, 인피니트 스크롤링이 적용된 페이지에 대해서 이미지를 다운하고 파일로 만드는 방법을 알아보았습니다 인스타그램,
tantangerine.tistory.com
앞서 웹 크롤링에서 중요한것은 태그를 찾는것이라 했습니다
하지만 중요한것이 하나 더있습니다
그것은 바로 비동기입니다
하지만 비동기에서도 순ㅍ차적 으로 실행할지 비순차적으로 할것인지가 중요 합니다
웹 크롤링할 경우 순차적으로 진행할 경우가 많기 때문에 비동기식이며 순차적인 방법이 중요합니다
이전 포스팅에서는 로그인할경우 아이디를 input 에 value 에 할당하여 한번에 아이디의 문자열이 모두 들어갔습니다
하지만 그렇게 된다면 유저가아닌 봇으로 의심을 받아 제재를 받을 수 있습니다
그래서 이 부분을 함수형으로 만들어 간결하게 만들어봅시다
아래 handleWriteInput 함수를 만들어서 process.env.EMAIL 을 id로 받아서 id를 확장 연산자를 사용해서
배열로 만들어서 로그인창에서 한글자씩 시간을 두고 글자를 입력하게됩니다
좀 더 자세한것은 아래에서 확인해보겠습니다
const puppeteer = require('puppeteer');
const writekeyboardList = require('./writekeyboardList');
const dotenv = require('dotenv'); // npm i dotenv
dotenv.config();
const setCrawler = async () => {
const browser = await puppeteer.launch({
headless: false,
args:['--window-size=1920,1080']
});
const page = await browser.newPage();
await page.setViewport({
width: 1080,
height:1080,
})
const handleWriteInuput = async (selector, id) => {
const writeList = writekeyboardList()
const idOfList = [...id]
await page.click(selector);
console.log(`idOfList`, idOfList)
for (const id of idOfList) {
const inputValue = await writeList.filter(element => element.ShiftLeft === id || element.key === id )
if (inputValue.length > 0) {
const code = inputValue[0].code
const ShiftLeft = inputValue[0].ShiftLeft === id ? 'ShiftLeft' : ''
if (ShiftLeft) {
await page.keyboard.down(ShiftLeft);
await setTime(selector, 500)
await page.keyboard.press(code);
await setTime(selector,500)
await page.keyboard.up(ShiftLeft);
} else {
await page.keyboard.press(code);
}
await setTime(selector,500)
}
}
}
const inputValue = async (selector, value) => {
await page.evaluate((selector, value) => {
document.querySelector(selector).value = value
}, selector, value)
await setTime(selector)
}
const buttonClick = async (selector, nextSelector, type) => {
await page.evaluate((selector) => {
document.querySelector(selector).click();
}, selector)
if(type === 'login'){
// waitForRequest(요청 대기), waitForResponse(응답 대기)
const res = await page.waitForResponse(res => {
return res.url().includes('graphql')
})
const result = await res.json()
console.log('login', result);
if(await result.extensions.is_final){
await setTime(type, 2000)
await page.keyboard.press('Escape')
}
} else if(type === 'logOut'){
await page.waitForNavigation()
} else {
if(nextSelector){
await page.waitForSelector(nextSelector)
}
await setTime(selector)
}
}
const setTime = async (selector = 'normal', waitTime = 0) => {
const setTime = await page.evaluate(async(waitTime) => {
const timeList = await [3975, 4547, 5231, 6397, 7894, 3394, 4206, 5147, 6932, 7430, 3561, 4896, 5877, 6407, 7133];
let randomTime = await timeList[Math.floor(Math.random() * timeList.length)]
if (waitTime > 0) randomTime = waitTime
await new Promise(r => setTimeout(r, randomTime))
return randomTime
}, waitTime)
console.log(`waitTime[${selector}]: `, setTime)
return setTime
}
return { buttonClick, inputValue, handleWriteInuput, setTime, page: page, browser: browser }
}
const crawler = async () => {
try {
const { buttonClick, inputValue, handleWriteInuput, setTime, page, browser } = await setCrawler();
await page.goto('https://facebook.com');
const id = await process.env.EMAIL;
const password = await process.env.PASSWORD;
// 로그인
//await inputValue('#email', id);
handleWriteInuput('#email', id)
await inputValue('#pass', password);
await buttonClick('[name="login"]', '', 'login');
// 로그아웃
await buttonClick('.i8zpp7h3', '.i1n1lj7b.mmwt03ec');
await buttonClick('.i1n1lj7b.mmwt03ec > div:last-child > div', '', 'logOut')
await page.close();
await browser.close();
} catch (e) {
console.log(e);
}
}
crawler()
아래의 함수를 확인하면 각자의 역할들이 존재합니다
아래에서 차근차근 설명해 보겠습니다
키보드 코드 사용하여 입력하기 함수형!
먼저 빨강 테두리의 함수는 키보드 코드 리스트가 담겨져 있으며,
require() 를 사용해서 파일에 접근해서 함수를 사용할 수 있게 합니다
웹크롤링 키보드 코드 파일
파일에는 아래와 같은 함수가 export되고 있습니다
code 가 위의 keyboard.press() 의 매개변수 인자값이 되며
Shift를 누른 상태 값은 ShiftLeft의 값이 대체 되어 값이 입력된다
module.exports = function writekeyboardList() {
const keyboard = [
{'keyCode': 48, 'code': 'Digit0', 'ShiftLeft': ')', 'key': '0'},
{'keyCode': 49, 'code': 'Digit1', 'ShiftLeft': '!', 'key': '1'},
{'keyCode': 50, 'code': 'Digit2', 'ShiftLeft': '@', 'key': '2'},
{'keyCode': 51, 'code': 'Digit3', 'ShiftLeft': '#', 'key': '3'},
{'keyCode': 52, 'code': 'Digit4', 'ShiftLeft': '$', 'key': '4'},
{'keyCode': 53, 'code': 'Digit5', 'ShiftLeft': '%', 'key': '5'},
{'keyCode': 54, 'code': 'Digit6', 'ShiftLeft': '^', 'key': '6'},
{'keyCode': 55, 'code': 'Digit7', 'ShiftLeft': '&', 'key': '7'},
{'keyCode': 56, 'code': 'Digit8', 'ShiftLeft': '*', 'key': '8'},
{'keyCode': 57, 'code': 'Digit9', 'ShiftLeft': '\(', 'key': '9'},
{'keyCode': 65, 'code': 'KeyA', 'ShiftLeft': 'A', 'key': 'a'},
{'keyCode': 66, 'code': 'KeyB', 'ShiftLeft': 'B', 'key': 'b'},
{'keyCode': 67, 'code': 'KeyC', 'ShiftLeft': 'C', 'key': 'c'},
{'keyCode': 68, 'code': 'KeyD', 'ShiftLeft': 'D', 'key': 'd'},
{'keyCode': 69, 'code': 'KeyE', 'ShiftLeft': 'E', 'key': 'e'},
{'keyCode': 70, 'code': 'KeyF', 'ShiftLeft': 'F', 'key': 'f'},
{'keyCode': 71, 'code': 'KeyG', 'ShiftLeft': 'G', 'key': 'g'},
{'keyCode': 72, 'code': 'KeyH', 'ShiftLeft': 'H', 'key': 'h'},
{'keyCode': 73, 'code': 'KeyI', 'ShiftLeft': 'I', 'key': 'i'},
{'keyCode': 74, 'code': 'KeyJ', 'ShiftLeft': 'J', 'key': 'j'},
{'keyCode': 75, 'code': 'KeyK', 'ShiftLeft': 'K', 'key': 'k'},
{'keyCode': 76, 'code': 'KeyL', 'ShiftLeft': 'L', 'key': 'l'},
{'keyCode': 77, 'code': 'KeyM', 'ShiftLeft': 'M', 'key': 'm'},
{'keyCode': 78, 'code': 'KeyN', 'ShiftLeft': 'N', 'key': 'n'},
{'keyCode': 79, 'code': 'KeyO', 'ShiftLeft': 'O', 'key': 'o'},
{'keyCode': 80, 'code': 'KeyP', 'ShiftLeft': 'P', 'key': 'p'},
{'keyCode': 81, 'code': 'KeyQ', 'ShiftLeft': 'Q', 'key': 'q'},
{'keyCode': 82, 'code': 'KeyR', 'ShiftLeft': 'R', 'key': 'r'},
{'keyCode': 83, 'code': 'KeyS', 'ShiftLeft': 'S', 'key': 's'},
{'keyCode': 84, 'code': 'KeyT', 'ShiftLeft': 'T', 'key': 't'},
{'keyCode': 85, 'code': 'KeyU', 'ShiftLeft': 'U', 'key': 'u'},
{'keyCode': 86, 'code': 'KeyV', 'ShiftLeft': 'V', 'key': 'v'},
{'keyCode': 87, 'code': 'KeyW', 'ShiftLeft': 'W', 'key': 'w'},
{'keyCode': 88, 'code': 'KeyX', 'ShiftLeft': 'X', 'key': 'x'},
{'keyCode': 89, 'code': 'KeyY', 'ShiftLeft': 'Y', 'key': 'y'},
{'keyCode': 90, 'code': 'KeyZ', 'ShiftLeft': 'Z', 'key': 'z'},
{'keyCode': 190, 'code': 'Period', 'ShiftLeft': '>', 'key': '.'},
]
return keyboard
};
더 많은 키보드 코드들을 알고 싶다면,
사이드 바에 공식문서 & 유용한 도구 목록을 확인해보세요!
웹크롤링 공식문서
그렇게 지정된 코드들을 아래의 특정 문자열을 받아와서 filter() 를 적용해서 code, ShiftLeft 를 가져옵니다
ShiftLeft 가 값이 할당되면 대문자라는 뜻이므로
대문자라면 keyboard.down(), keyboard.up() 을 적용합니다
아래의 함수를 선언해서 handleWrite 를 호출하는 것만으로 간단하게 적용할 수 있습니다
또 한, for(const id of idOfList) 에서 비동기식 순차적으로 실행하게되어
글자를 한글자씩 입력하게됩니다
for (const id of idOfList) {
const inputValue = await writeList.filter(element => element.ShiftLeft === id || element.key === id )
if (inputValue.length > 0) {
const code = inputValue[0].code
const ShiftLeft = inputValue[0].ShiftLeft === id ? 'ShiftLeft' : ''
if (ShiftLeft) {
await page.keyboard.down(ShiftLeft);
await setTime(selector, 500)
await page.keyboard.press(code);
await setTime(selector,500)
await page.keyboard.up(ShiftLeft);
} else {
await page.keyboard.press(code);
}
await setTime(selector,500)
}
}
이렇게 웹크롤링에서 키보드 코드를 입력해서 사용자 친화적으로 만들어서
봇으로 의심을 조금이라도 피하게하기위함입니다
웹크롤링의 포스팅 글이 점점 길어지고 있습니다
그래도 알게되는 것도 많으며, 앞으로 확실히 나아가는 것같습니다
그럼 다음 포스팅도 기대해주시고
다음 웹 크롤링 관련 글로 찾아뵙겠습니다
대모험이 끝나기를 기대하며 화이팅!