728x90
크롤링과 스크래핑 차이
크롤링 - URL을 탐색해 반복적으로 링크를 찾고 가져오는 과정
스크래핑 - 우리가 정한 특정 웹 페이지에서 데이터를 추출하는 것
웹 크롤링은 불법인가?
- 웹사이트의 홈 디렉터리에 위치한 robots.txt 파일을 열어보고 해당 사이트의 정책을 준수하지 않는다면 불법
- 크롤링한 자료를 상업적 용도로 사용하면 불법
- 비상업적인 용도라 하더라도 원작자에게 불이익을 주면 불법
- 크롤러를 활용해 고의적으로 Abusing(조작) 하면 불법
- robots.txt 보는법 - https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=http-log&logNo=221104827805
- 크롤링은 불법인가 - https://pythontoomuchinformation.tistory.com/363
- '여기어때 무죄'로 본 '크롤링'...합법과 불법 사이 -https://www.ajunews.com/view/20220515155129332
NodeJs로 간단한 크롤러 만들기
npm init 및 모듈 설치
npm init -y
// 크롤링을 도와주는 모듈
npm i puppeteer
app.js
필요 모둘 불러오기
// 크롤링하기위한 puppeteer 모듈 불러오기
const puppeteer = require("puppeteer");
// 데이터를 저장하기위해 fs 모듈 불러오기
const fs = require("fs");
app.js
우리 포켓몬 사이트를 스크랩 해올 scrape 함수 만들기
async function scrape() {
try {
// 크로미움으로 브라우저를 연다.
const browser = await puppeteer.launch();
// 페이지 열기
const page = await browser.newPage();
// 링크 이동
await page.goto("<http://127.0.0.1:5555>");
// .card 엘리먼트중에 값이 #100인 .card--id 엘리먼트가 생길때까지 기다림
await page.waitForFunction(
() =>
document.querySelector(".card:last-child .card--id").textContent ===
"#100",
{ timeout: 5000 }
);
// cards 에 모든 카드정보 배열로 저장
const cards = await page.$$(".card");
// 100개의 카드가 잘 저장되었는지 확인.
console.log(cards.length);
const data = [];
// cards 돌면서 필요한 데이터 수집
// data 배열에 수집한 데이터 등록
for (const card of cards) {
const id = await card.$eval(".card--id", (el) => el.textContent);
const image = await card.$eval(".card--image", (el) =>
el.getAttribute("src")
);
const name = await card.$eval(".card--name", (el) => el.textContent);
const details = await card.$eval(
".card--details",
(el) => el.textContent
);
data.push({ id, image, name, details });
}
// 페이지와 브라우저 종료
await page.close();
await browser.close();
// data 리턴 => 리턴한 데이터를 받아서 파일로 쓰기 위함.
return data;
} catch (error) {
console.log(error);
}
}
- page.$$() - https://pptr.dev/api/puppeteer.page.__
- puppeteer 참고 - https://tlqckd0.tistory.com/48
app.js
스크랩 완료 후 데이터 json파일로 저장
scrape()
.then((data) => {
fs.writeFile("pokemon.json", JSON.stringify(data), "utf8", (error) => {
if (error) {
console.log("파일 생성 중 에러 발생.");
return console.log(error);
}
console.log("파일 생성 완료!");
});
})
.catch((error) => console.log(error));
pokemon.json 파일에 정보가 잘 들어 왔느지 확인!
js 를 ts로 바꾸기
// require => import 로 변경
// 크롤링하기위한 puppeteer 모듈 불러오기
import puppeteer from "puppeteer";
// 데이터를 저장하기위해 fs 모듈 불러오기
import fs from "fs";
// 작성필요 - 인터페이스 내부 값
interface ICard {
id: string;
name: string;
image: string;
details: string;
}
async function scrape(): Promise<ICard[]> { // 작성필요 - 함수 반환 타입
try {
// 크로미움으로 브라우저를 연다.
const browser = await puppeteer.launch();
// 페이지 열기
const page = await browser.newPage();
// 링크 이동
await page.goto("http://127.0.0.1:5500/day3-pokemon/");
// .card 엘리먼트중에 값이 #100인 .card--id 엘리먼트가 생길때까지 기다림
await page.waitForFunction(
() => {
const cardId = document.querySelector(".card:last-child .card--id");
return cardId && cardId.textContent === "#100";
},
{ timeout: 7000 }
);
// cards 에 모든 카드정보 배열로 저장
const cards = await page.$$(".card");
// 100개의 카드가 잘 저장되었는지 확인.
console.log(cards.length);
const data: ICard[] = [] // 작성필요 - data 타입 = [];
// cards 돌면서 필요한 데이터 수집
// data 배열에 수집한 데이터 등록
for (const card of cards) {
const id = await card.$eval(".card--id", (el) => el.textContent);
const image = await card.$eval(".card--image", (el) =>
el.getAttribute("src")
);
const name = await card.$eval(".card--name", (el) => el.textContent);
const details = await card.$eval(
".card--details",
(el) => el.textContent
);
// 작성필요 - id, image, name, details 에러처리 필요
if (id && image && name && details ) {
data.push({ id, image, name, details });
} else {
return [];
}
}
// 페이지와 브라우저 종료
await page.close();
await browser.close();
// data 리턴 => 리턴한 데이터를 받아서 파일로 쓰기 위함.
return data;
} catch (error) {
console.log(error);
return [];
// 작성필요 - 리턴값 필요
}
}
scrape()
.then((data) => {
fs.writeFile("pokemon.json", JSON.stringify(data), "utf8", (error) => {
if (error) {
console.log("파일 생성 중 에러 발생.");
return console.log(error);
}
console.log("파일 생성 완료!");
});
})
.catch((error) => console.log(error));
'코딩캠프 > 내일배움캠프' 카테고리의 다른 글
[ WIL ] 01.16~20 10주차 (0) | 2023.01.22 |
---|---|
[ TIL ] 01.20(금) 50일차 (0) | 2023.01.20 |
[ TIL ] 01.18(수) 48일차 (0) | 2023.01.18 |
[ TIL ] 01.17(화) 47일차 (0) | 2023.01.17 |
[ TIL ] 01.16(월) 46일차 (0) | 2023.01.16 |