npm i csv-parse
: csv를 parse하는 모듈//모듈을 사용하기 위한 부분
const parse = require('csv-parse/lib/sync');
//csv 파일을 읽어오기 위한 모듈
const fs = require('fs');
//csv는 버퍼형식임. csv파일을 읽어옴
const csv = fs.readFileSync('csv/data.csv');
//0,1로 이루어진 버퍼를 문자열로 변환해줌
//parse메서드가 문자열을 2차원 배열로 바꿔줌
const records = parse(csv.toString('utf-8'));
records.forEach((r, i) => {
console.log(i, r);
});
const xlsx = require('xlsx');
//readfile로 엑셀파일 읽기
const workbook = xlsx.readFile('xlsx/data.xlsx');
console.log(Object.keys(workbook.Sheets)); // TODO: workbook.SheetNames
const ws = workbook.Sheets.영화목록;
const records = xlsx.utils.sheet_to_json(ws); // TODO: 강좌에서 header 옵션 보여주기
//entries()로 사용하면 객체가 [인덱스, 값]형태 이터레이터로 변환됨.
for (const [i, r] of records.entries()) {
console.log(i, r);
}
가장 간편하게 크롤링하는 방법
axios + cheerio 조합으로 가능
const xlsx = require('xlsx');
const axios = require('axios');
const cheerio = require('cheerio');
const add_to_sheet = require('./add_to_sheet');
const workbook = xlsx.readFile('xlsx/data.xlsx');
const ws = workbook.Sheets.영화목록;//work sheet
const records = xlsx.utils.sheet_to_json(ws);
const crawler = async () => {
add_to_sheet(ws, 'C1', 's', '평점');
await Promise.all(records.map(async (r) => {
//promise.all은 동시에 진행되지만 순서는 보장되지 않음.
//링크에 get요청을 보낸다
const response = await axios.get(r.링크);
//요청이 성공했으면,
if (response.status === 200) {
const html = response.data;
//html = html 문자열 cheerio로 로드-> 태그들에 접근 가능함
const $ = cheerio.load(html);
//css선택자로 원하는 태그를 선택할 수 있어야한다.
const text = $('.score.score_left .star_score').text();
console.log(r.제목, '평점', text.trim());
const newCell = 'C' + (i + 2);
add_to_sheet(ws, newCell, 'n', text.trim()); // 액셀에 쓰기 위한 파일호출 1.8장에 내용 있음
}
}));
xlsx.writeFile(workbook, 'xlsx/result.xlsx'); // 엑셀에 새로 쓰기
};
crawler();
Promise.all
은 동시에 진행되고 순서가 보장되지 않음
for of
문은 순서를 보장해줌
promise.all
은 한번에 여러 요청을 보낼 수 있어서 속도가 엄청 빠르나 for of
는 하나를 보내고 응답을 받고나서야 다시 요청을 보내기 떄문에 순서가 보장되나 느림순서가 보장하려면 for of + await
를 같이 쓰면 된다
const crawler = async() => {
for (const [i, r] of records.entries()){
const response = await axios.get(r.링크);
if (response.status === 200) {
const html = response.data;
//html = html 문자열 cheerio로 로드-> 태그들에 접근 가능함
const $ = cheerio.load(html);
//css선택자로 원하는 태그를 선택할 수 있어야한다.
const text = $('.score.score_left .star_score').text();
console.log(r.제목, '평점', text.trim());
}
}
}
axios로 요청했을 때 HTML응답을 반환하지 않는 페이지도 있음.
puppeteer
로는 가능함axios cheerio
크롤링된 데이터에 컬럼명의 속성을 가지게 할 수 있음
const records = xlsx.utill.sheet_to_json(ws, {header : 'A });
: header를 추가함.패키지사용
: ws['!ref']; -> 파싱할 데이터 구역을 반환함 (A1 : B11) A1부터 ~ B11까지 파싱할 범위를 지정함.
const workbook = xlsx.readFile('xlsx/data.xlsx'); -> workbook.SheetNames
로 Sheet이름들을 반환받을 수 있음
node에서 액셀에 글을 작성하려면 파일을 작성해야함.
const xlsx = require('xlsx');
function range_add_cell(range, cell) {
var rng = xlsx.utils.decode_range(range);
var c = typeof cell === 'string' ? xlsx.utils.decode_cell(cell) : cell;
if (rng.s.r > c.r) rng.s.r = c.r;
if (rng.s.c > c.c) rng.s.c = c.c;
if (rng.e.r < c.r) rng.e.r = c.r;
if (rng.e.c < c.c) rng.e.c = c.c;
return xlsx.utils.encode_range(rng);
}
module.exports = function add_to_sheet(sheet, cell, type, raw) {
sheet['!ref'] = range_add_cell(sheet['!ref'], cell);
sheet[cell] = { t: type, v: raw };
};
add_to_sheet(ws, 'C1' , 's', '평점');