Node.js로 웹 크롤링하기
Node.js로 웹 크롤링하기
수강정보
(14개의 수강평)
302명의 수강생
55,000원
지식공유자 : 조현영
75회 수업 · 총 13시간 36분 수업
기간 : 평생 무제한 시청
수료증 : 발급 강의
수강 난이도 : 중급이상
주홍철 프로필

node.js 싱글코어 주홍철 13일 전
node.js는 싱글코어라 fs pipe stream을 사용한다고 핫겼는데 node.js가 싱글코어인가요?

1
new code 프로필

puppeteer 는 GUI 환경에서만 실행할수있나요? new code 1달 전
headless = true 라면 일반 커멘드라인 리눅스환경에서도 작동이 될까요? 클라우드환경에서 작동시키고 싶어서요

1
ㅁㄴㅇㄼㅈㄷㄱ 프로필

js 동기처리에 대해 질문드립니다(2) ㅁㄴㅇㄼㅈㄷㄱ 2달 전
여전히 같은 문제가 발생하여 다시 질문합니다 말씀해주신대로 'end' 이벤트 부분에서 resolve를 해주었지만 실제로 then 부분에서 promise가 resolve되지 않는것 같습니다... 정말 죄송한데 코드 한번만 확인해주실수 있나요??ㅠㅠ..  실제로 resolve하는 부분은 ./js/index.js 파일에 있고, promise 함수는 ./js/downloader.js 파일에 있습니다 (retry 함수는 에러가 발생했을 때, 30번 까지 다시 시도해주는 함수입니다. 이부분 역시 promise로 만들었습니다)

3
ㅁㄴㅇㄼㅈㄷㄱ 프로필

js 동기처리에 대해 질문드립니다 ㅁㄴㅇㄼㅈㄷㄱ 2달 전
혼자 해보려고 했는데 너무 안되서 질문합니다 ㅜㅜ.. // downloader.js const downloader = (url ,title) => {     ytdl(url).pipe(fs.createWriteStream(`./${title}.mp4`));     ffmpeg(`./${title}.mp4`)     .pipe(fs.createWriteStream(`./${title}.mp4`), {end: true})     } // changeMetadata.js function changeMetadata(path, title) {     let data = nodeID3.read(path);     let tags = {}     nodeID3.write(tags, path); } 위에서 downloader(); changeMetadata(); 를 실행했을 때, downloader의 모든 실행이 완벽하게 완료된 후 changeMetadata를 실행하고 싶습니다. 위 두함수 모두 Promise 형태로 바꾸어서 await를 붙이거나, async.waterFall .. 을 해봤는데 제가 문법을 못쓰는건지, 아니면 다른 방법으로 해야되는건지 전부 안되더라구요.. 위와 같은 상황에서 동기식으로 처리하는 방법과 간단하게 코드 스케치정도 부탁드립니다!!! 위 처럼 함수 두개가 있고 firstFunction의 모든 작업이 완전히 끝난 다음에 secondFunction이 실행될 수 있도록 하고 싶습니다.

1
JY C 프로필

ELECTRON으로 UI생성 후 퍼피티어 호출 JY C 2달 전
안녕하세요 선생님 항상 강의 잘보고 있습니다. 선생님의 퍼피티어 크롤러를 일렉트론으로 UI를 생성후 실행해보고있는데 그냥 코드 실행하면 되는데 일렉트론에서 실행을 하면  Error passed function is not well serializable이라는 오류가 뜹니다. 이 에러를 어떻게 해결할수 있을까요? JSON.stringfy로 ""를 달고 evaluate에 문자열로 넘겨주면 되긴하는데 너무불편하고 다른 함수들이 작동하지 않습니다(waitfor등) "puppeteer-in-electron": 모듈을 사용하는 방법외에 해결할 방법이 궁금합니다. https://www.google.com/search?q=Error+passed+function+is+not+well+serializable&oq=err&aqs=chrome.0.69i59j69i57j0l3j69i61l2j69i60.3880j0j7&sourceid=chrome&ie=UTF-8

3
ㅁㄴㅇㄼㅈㄷㄱ 프로필

axios 에러 질문있습니다 ㅁㄴㅇㄼㅈㄷㄱ 2달 전
혼자 해결해보려고 했는데 너무 안돼서 질문합니다. axios를 사용해서 다음 뉴스기사를 크롤링하고 있는데 이게 url이 적을때는 잘 작동을 하는데 많아지면 계속 아래와 같은 에러가 발생합니다. (동일한 요청을 request로 했을 때는 정상작동합니다) Error: read ECONNRESET  at TLSWrap.onStreamRead (internal/stream_base_commons.js:205:27) 검색해보니 axios로 요청을 한번에 많이 보내면 발생할 수 있다고 하는데 솔직히 정확한 원인과 해결방법을 잘 모르겠습니다.. 처음에는 setInterval로 1분 단위로 나누어서 보내기도 했는데 너무 느리고 맞는 해결법이 아닌것 같더라구요.. 혹시 해결할 수 있는 방법이 있을까요??.. 전체 코드는 아래와 같습니다 const axios = require('axios'); const cheerio = require('cheerio'); let count=0; const findOutNewsLink = async () => {     const categories = ['society', 'politics', 'economic', 'foreign', 'culture', 'digital'];          let urlArray = [];     for(let i=0; i<categories.length; i++) {         for(let day=1; day<=5; day++) {             for(let page=1; page<=20; page++) {                 // await getSome(categories[0], page, day);                 urlArray.push(`https://news.daum.net/breakingnews/${categories[i]}?page=${page}&regDate=202006${pad(day, 2)}`)             }         }     }     getSome(urlArray, categories[0]);     } const getSome = async (urlArray, category) => {     try {         await Promise.all(urlArray.map(async (url) => {             const res = await axios.get(url);             if(res.status === 200) {                 const $ = cheerio.load(res.data);                 const aArr = $('a');                                  let newsArr = [];                                  for(let i=0; i<aArr.length; i++)                      if(aArr[i].attribs.href.includes('https://v.daum.net/v/')) newsArr.push(aArr[i].attribs.href);                 newsArr = Array.from(new Set(newsArr));                 // for(let i=0; i<newsArr.length; i++)                 //     findOutContent(newsArr[i], category);                 findOutContent(newsArr, category);             }         }));     }     catch (err) {         console.error(err);     } } const findOutContent = async (newsArr, category) => {     try {         await Promise.all(newsArr.map( async(newsURL) => {             const res = await axios.get(newsURL);             const $ = cheerio.load(res.data);             const title = $('.tit_view')[0].children[0].data;             let contentArr = $('#harmonyContainer p');             let content = "";             for(let i = 0; i < contentArr.length; i++) {                 if(contentArr[i].children[0] === undefined || contentArr[i].children[0].data === undefined) continue;                 content += contentArr[i].children[0].data + " ";             }                          const newsObject = {                 title,                 content,                 category             }             console.log(count);             count++;         }))     }     catch(err) {         console.error(err);     } } const pad = (n, width, z) => {     z = z || '0';     n = n + '';     return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; } findOutNewsLink();

1
inflearn1 프로필

제로초님 크롤링 최적화 질문 있습니다. inflearn1 2달 전
아무래도 네이버나  대형 포털은 이미지가 많아서 로딩 시간이 상당히 길어지는 경우가 많습니다.. 화면 전체를 스크린샷 해야하는데 이미지 때문에 시간이 오래걸리네요..(이미지는 있어야합니다)  puppetteer 기능이나 관련 플러그인중에 이미지 로딩을 최적화 할 수 있는 방법이 있을까요? 현재 css와 폰트는 disable 한 상태입니다.

2
inflearn1 프로필

Error: net::ERR_TOO_MANY_REDIRECTS at 에러 복구 불가인가요? inflearn1 3달 전
평소 잘 돌아가던게 프로그램을 서버이전하고 하루 돌렸는데 저 에러가 발생하고 실행할때 마다 저 에러가 계속발생하네요... 웹서버에서 아이피를 차단한거 같은데 해결방법은 없는건가요?

2
지우지 프로필

throw new Error 지우지 3달 전
개별적인 try...catch보다 throw new Error(...)를 쓰면 좋지 않나요?

2
김도영 프로필

크롤러 요청 제한 김도영 3달 전
안녕하세요 제로초님,  puppteer에서 이미지 캡쳐를 요청 하면 새로운 페이지를 만들고 캡쳐후 close 하게끔 간단한 과정을 만들었습니다. 한 3~5개는 괜찮은데, 10개의 page를 한번에 캡쳐하려니, 브라우저 페이지가 먹통이 됩니다.  그래서 요청에 제한을 두려하는데 어떤 키워드로 찾아야 할지 모르겠어요..  HTTP Server 는 graphql-yoga(express) 를 붙혔고 요청이 5개 이상일때는 대기하라 라고 명하고 싶은데.  관련된 미들웨어 혹은 키워드가 있을까요? 

1
inflearn1 프로필

evaluate() 메서드 내에서 어떻게 딜레이를 적용할 수 있나요? inflearn1 4달 전
구글링을 통해 다양한 자료를 봤는데 명확한 답을 얻지 못하여 글을 남깁니다. page.waitFor 과 같은 함수를 evaluate() 함수 내에서 어떻게 구현할 수 있나요?

1
haemil 프로필

6-1. 프록시 설명과 태그 분석 강의를 보고 질문드립니다. haemil 4달 전
안녕하세요 제로초님 [6-1. 프록시 설명과 태그 분석] 강의를 보고 궁금한 점이 생겨서 질문드립니다. 아래 코드에서 Array.from() 의 역할이 무엇인지 잘 모르겠습니다. ㅠㅠ... Array.from()을 MDN에서 찾아보니 유사 배열 객체(array-like object)나반복 가능한 객체(iterable object)를 얕게 복사해새로운Array 객체를 만든다고 하는데  Array.from() 으로 감싸기 전의 DOM API로 선택한 요소들(document.querySelectorAll('tr > td:first-of-type > .spy14'))을 왜 새롭게 Array 객체로 만드는 걸까 의문이 들어서 질문드립니다.  음 학습하면서 추론해보는 내용인데 혹시 DOM API로 선택한 유사배열 객체를 Array.from() 으로 감싸지 않으면 `map()` 함수를 쓸 수 없기 때문에 감싸는 것인가요? 아니면 혹시 다른 이유가 있는 것인지 궁금합니다. ```javascript Array.from(document.querySelectorAll('tr > td:first-of-type > .spy14')).map(v => v.textContent.replace(/document\.write\(.+\)/, '')); ``` 강의 잘 보고 있습니다. 제로초님 건강하세요

2
trip trip 프로필

콘솔에서 $문제 trip trip 4달 전
세션 2까지 수업을 들은 상태입니다. 네이버에서는 $를 이용하면 검색이 잘 되는데 카카오 페이지에서는 콘솔에서 검색을 할 때 $함수가 존재하지 않는다고 뜹니다. $$과 [0]를 이용하면 찾을 수는 있는데 그냥 경로만 찾으면 저런 것들은 문제가 없는 건가요?

1
kim rea 프로필

순차적으로 5개페이지 한번에 kim rea 4달 전
선생님 저도 이부분에서 막히네요 ㅜㅜ for of 을 써서 순차적으로 엑셀의 링크를 불러와서  크롤링하는데 한번에 5개씩 동시에 작업하고 싶어요 1,2,3,4,5 링크 쭉 가져와서 페이지 5개 한번에 열어서 크롤링하고 저장 6,7,8,9,10  링크 쭉 가져와서 페이지 한번에 열어서 크롤링 후 저장 promise all 을 써야되는걸 아는데 자세히 알수있을까요 ㅜㅜ 순차적으로 몇만개 크롤링하니까 시간이 너무걸리는것 같아서 동시에 처리하고싶어요

1
최현성 프로필

puppeteer 3버전 관련 최현성 5달 전
안녕하세요 제로초님 강의 잘 보고 있습니다 :) 현재 강의에서 쓰신 버전은 1점대 버전인데, 현시점 install 되는 버전은 3점대 버전이네요; 혹시 라이브러리 메소드 사용에 있어서 다른점이 많을까요?

1
지식공유자 되기
많은 사람들에게 배움의 기회를 주고,
경제적 보상을 받아보세요.
지식공유참여
기업 교육을 위한 인프런
“인프런 비즈니스” 를 통해 모든 팀원이 인프런의 강의들을
자유롭게 학습하는 환경을 제공하세요.
인프런 비즈니스