csv 파일을 읽어서 각각 페이지들을 csv에 적혀있는 주소들에 접근해서
접근한 경우 page의 .score.score_left .star_score을 가져온다 .
만약에 scroeEl가 정상적로 받아와졌다면
태그의 값을 textContent로 가져온다
const parse = require("csv-parse/lib/sync");
const fs = require("fs");
const puppeteer = require("puppeteer");
const csv = fs.readFileSync("./csv/data.csv");
//parse 메서드 -> 2차원배열화
const records = parse(csv.toString());
// console.log(records);
const crawler = async () => {
const browser = await puppeteer.launch({ headless: false });
try {
await Promise.all(
records.map(async (r, i) => {
try {
const page = await browser.newPage();
// 페이지가 띄워졌을때
await page.goto(r[1]);
//접근
const scoreEl = await page.$(".score.score_left .star_score");
if (scoreEl) {
//찾은 태그를 통해서
//textContent를 가져오기
const text = await page.evaluate((tag) => tag.textContent, scoreEl);
console.log(r[0], '평점', text.trim());
}
//사람인척 하는 트릭
await page.waitFor(3000);
await page.close();
} catch (err) {
console.log(err);
}
})
);
} catch (err) {
console.log(err);
} finally{
await browser.close();
}
};
crawler();
csv-stringify 모듈을 추가해준다
parse는 일반 문자열을 배열 형태로 변경해줬기때문에
stringify는 배열형태를 일반 문자열로 바꾸어서
파일시스템을 활용해서 작성할 수 있도록 해준다.
const parse = require("csv-parse/lib/sync");
const fs = require("fs");
const stringify = require('csv-stringify/lib/sync');
const puppeteer = require("puppeteer");
console.log(__dirname);
const csv = fs.readFileSync(__dirname+"/csv/data.csv");
//parse 메서드 -> 2차원배열화
const records = parse(csv.toString());
// console.log(records);
const crawler = async () => {
const browser = await puppeteer.launch({ headless: false });
try {
const result = [];
await Promise.all(
records.map(async (r, i) => {
try {
const page = await browser.newPage();
// 페이지가 띄워졌을때
await page.goto(r[1]);
//접근
const scoreEl = await page.$(".score.score_left .star_score");
if (scoreEl) {
//찾은 태그를 통해서
//textContent를 가져오기
const text = await page.evaluate((tag) => tag.textContent, scoreEl);
console.log(r[0], '평점', text.trim());
result.push([r[0], r[1], text.trim()]);
}
//사람인척 하는 트릭
await page.waitFor(3000);
await page.close();
const str = stringify(result);
fs.writeFileSync("csv/result.csv", str);
} catch (err) {
console.log(err);
}
})
);
} catch (err) {
console.log(err);
} finally{
await browser.close();
}
};
crawler();
이렇게 진행하면 원본의 순서와 달라지게 된다
result.push 부분을
아래와같이 리팩토링을 진행하면
const parse = require("csv-parse/lib/sync");
const fs = require("fs");
const stringify = require('csv-stringify/lib/sync');
const puppeteer = require("puppeteer");
console.log(__dirname);
const csv = fs.readFileSync(__dirname+"/csv/data.csv");
//parse 메서드 -> 2차원배열화
const records = parse(csv.toString());
// console.log(records);
const crawler = async () => {
const browser = await puppeteer.launch({ headless: false });
try {
const result = [];
await Promise.all(
records.map(async (r, i) => {
try {
const page = await browser.newPage();
// 페이지가 띄워졌을때
await page.goto(r[1]);
//접근
const scoreEl = await page.$(".score.score_left .star_score");
if (scoreEl) {
//찾은 태그를 통해서
//textContent를 가져오기
const text = await page.evaluate((tag) => tag.textContent, scoreEl);
console.log(r[0], '평점', text.trim());
result[i] = [r[0], r[1], text.trim()] ;
}
//사람인척 하는 트릭
await page.waitFor(3000);
await page.close();
const str = stringify(result);
fs.writeFileSync("csv/result.csv", str);
} catch (err) {
console.log(err);
}
})
);
} catch (err) {
console.log(err);
} finally{
await browser.close();
}
};
crawler();
이제 정상적으로 순서가 보장된 채로 출력이 된다.
Evaluate를 활용한 리팩토링
evaluate안에서는 document.querySelector등 선택자가 사용이 가능하기때문에
eavaluate 안에서 선택자를 통해 가져오는 방식으로 리팩토링이 가능하다
const parse = require("csv-parse/lib/sync");
const fs = require("fs");
const stringify = require('csv-stringify/lib/sync');
const puppeteer = require("puppeteer");
console.log(__dirname);
const csv = fs.readFileSync(__dirname+"/csv/data.csv");
//parse 메서드 -> 2차원배열화
const records = parse(csv.toString());
// console.log(records);
const crawler = async () => {
const browser = await puppeteer.launch({ headless: false });
try {
const result = [];
await Promise.all(
records.map(async (r, i) => {
try {
const page = await browser.newPage();
// 페이지가 띄워졌을때
await page.goto(r[1]);
//접근
// const 태그 핸들러 = await page.${선택자};
const text = await page.evaluate(() => {
// 이안에서 document는 사용이 가능하다
const score = document.querySelector(".score.score_left .star_score");
if(score){
return score.textContent;
}
});
if(text){
console.log(r[0], '평점', text.trim());
result[i] = [r[0], r[1], text.trim()];
}
//사람인척 하는 트릭
await page.waitFor(3000);
await page.close();
const str = stringify(result);
fs.writeFileSync("csv/result.csv", str);
} catch (err) {
console.log(err);
}
})
);
} catch (err) {
console.log(err);
} finally{
await browser.close();
}
};
crawler();
'Node.js > node crawling' 카테고리의 다른 글
노드 크롤링 - userAgent와 한탭으로 크롤링 (0) | 2020.08.16 |
---|---|
노드 크롤링 - puppeteer의 다양한 기능들 (0) | 2020.08.15 |
노드 크롤링 - puppeteer 사용해보기 (0) | 2020.08.15 |
노드 크롤링 - 네이버 영화 크롤링하기, 엑셀에 작성하기 (0) | 2020.08.15 |
노드 크롤링 - csv 파일, 엑셀파일(xlsx) 파싱하기 (0) | 2020.08.15 |