[크롤링 로그인] 노션 메일주소로 로그인하기

jehjong·2020년 9월 29일
0

크롤링

목록 보기
4/5
post-thumbnail

🤘 dotenv

.env에 보안이 필요한 정보를 입력하고 보관하면 다른 코드가 유출되어도 보안유지 가능

설치

npm i dotenv

.env에 입력

  • .env 파일에 메일주소와 비밀번호 등의 정보 입력
EMAIL=[email address]
PASSWORD=[password]
...

사용법

  • 사용할 페이지에 dotenv 불러오기
//index.js
const dotenv = require('dotenv');
dotenv.config();
  • 아래 형식으로 값 불러와서 사용
process.env.EMAIL;
process.env.PASSWORD

🤘 waitUntil

networkidle0networkidle2를 사용해봤는데 사실 차이를 아직 잘 모르겠다

  • 둘 다 이미지나 페이지 등의 리소스가 다 로드되기를 기다리는 것인 것
  • 충분히 로드되어야 태그와 selector를 찾을 수 있다

Puppeteer has "networkIdle0" (0 network connections for 500ms) and "networkIdle2" (no more than 2 network connections for 500ms).
<출처> https://news.ycombinator.com/item?id=16461979

<출처> 5번째 댓글

networkidle0

await page.goto('https://www.~', {
	waitUntil: 'networkidle0'
})
  • 페이지 안 컨텐츠가 다 로딩될 때까지 기다린다 (예. 싱글페이지 어플리케이션)
  • 쓰면 안되는 경우: 유투브 (영상 다 로딩되기까지 기다리면 한참 걸림)

networkidle2

페이지 전체가 로딩되는 것이 아니면 사용하면 안된다

await page.waitForNavigation({
	waitUntil: 'networkidle2,
})

아래의 과정에서는 4번 후에만 waitUntil: networkidle2를 사용해야한다

🚨 1, 2, 3번 후에 적용 시 다음 단계로 안 넘어간다
  1. 노션에서의 로그인창에 메일주소를 입력한다
  1. "Continue with email"을 클릭하면 비밀번호 입력창이 뜬다
  1. 비밀번호를 입력한다
  1. "Continue with login code"을 클릭하면 노션페이지로 이동한다

🤘 waitForSelector

원하는 버튼을 클릭하기 위해서 제로초는 두 단계를 사용한다.

await page.waitForSelector('selector');
await page.click('selector');

DOM selector가 충분히 로딩되기를 기다리는 것인데 이번 로그인의 경우는 없어도 잘 되는 것을 확인했다.

🤘 Copy selector

  • selector를 찾기 힘들다면 태그 우클릭 후 Copy selector를 하면 편하다
  • Copy JS path를 하면 위 selector를 document.querySelector()안에 넣어준다

Selector 최적화

selector를 필수태그만 남겨 최소화하는 과정을 뜻한다
🚨 복사한 Selector는 정확하게 한 곳을 가리키지만 불필요하게 긴 경우가 많으므로 최적화해주는 것이 좋다

  • Console에서 하나씩 지우며 계속 같은 곳을 가리키는지 확인해보면 된다
예시
// Copy한 selector
$('#notion-app > div > div:nth-child(1) > main > section > div > div > div > div.notion-login > div:nth-child(3) > div.notion-focusable > input[type=email]')
// 최적화한 selector
$('input[type=email]')


// Copy한 selector
$('#notion-app > div > div:nth-child(1) > main > section > div > div > div > div.notion-login > div:nth-child(3) > div:nth-child(6)')
// 최적화한 selector
$('.notion-login div:nth-child(6)')

🤘 Type and value

type

selector에 글자 하나씩 입력하는 방식으로 덜 로봇같다

await page.type('selector', process.env.EMAIL);
단점
  • 유투브 등은 type으로 입력이 안돼 value를 사용해야 한다

value

selector에 값을 바로 입력해버리는 방식

await page.evaluate((email) => {
	document.querySelector('selector').value = email;
}, process.env.EMAIL);

// await page.evaluate((변수) => {
//	...
// }, 변수에 넘겨줄 값)
단점
  • type처럼 타자를 치는 모션 없이 값이 한번에 입력된다.

    • page.waitFor(3000)등으로 기다려줘야 덜 로봇같다
  • 이번 노션 로그인에서는 아래와 같은 에러가 떴고 type으로 입력시 해결되었다

Failed to load resource: ther server Failed to load resource: the server responded with a status of 404 () cs.moz.com/id?
Http Request Error: Invalid email address

🤘 노션 로그인 완성 코드

const fs = require('fs');
const puppeteer = require('puppeteer');
const axios = require('axios');
const stringify = require('csv-stringify/lib/sync');
const dotenv = require('dotenv');
dotenv.config();


const crawler = async () => {
	try{
		const browser = await puppeteer.launch({ 
			headless: false,
		});	//브라우저 띄우기
		const page = await browser.newPage();	//페이지 띄우기
		await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36');
		await page.goto('https://www.notion.so/42-1fb86e5e2cb7475d96cbb7f693d50dd7', {
			waitUntil: 'networkidle0'
		})

		// notion logo click
		await page.waitForSelector('.notion-topbar div:nth-child(6)');
		await page.click('.notion-topbar div:nth-child(6)');


		// type email
		await page.waitForSelector('input[type=email]');
		await page.type('input[type=email]', process.env.EMAIL);


		// click "Continue with email"
		await page.waitForSelector('.notion-login div:nth-child(4)');
		await page.click('.notion-login div:nth-child(4)');

		
		// type password
		await page.waitForSelector('input[type=password]');
		await page.type('input[type=password]', process.env.PASSWORD);

		
		// click "Continue with password"
		await page.waitForSelector('.notion-login div:nth-child(6)');
		await page.click('.notion-login div:nth-child(6)');


		// await page.close();		//페이지 닫기
		// await browser.close();	//브라우저 닫기
	} catch (e) {
		console.error(e);
	}
}

crawler();
profile
jehong@42Seoul

0개의 댓글