일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 동기 함수 내에서 비동기 함수 호출
- 리액트최적화
- 상단 빈공간 제거
- SwiftUI Font
- access network
- react fsd
- @observedobject 프로퍼티 래퍼
- react-router-dom
- 가로모드끄기
- 페이지이동함수
- 세로모드끄기
- C++
- CSS
- 비동기함수
- 리렌더링최적화
- physical media
- featured-sliced-design
- 반응형 css
- @published 프로퍼티 래퍼
- 페이지전환
- BFS
- 컴퓨터네트워크
- react hook
- network core
- @environmentobject 프로퍼티 래퍼
- LazyVGrid
- GridItem
- LazyHGrid
- 블로그업로드확인
- navigationBar 숨기기
- Today
- Total
leebaek
[JS] 블로그 업로드 확인하는 크롤러 | 날짜 크롤러 본문
블로그 커피빵 ☕️
■ 전체적인 개발 틀
■ 날짜 크롤링 과정
■ 정해진 날에 크롤링 코드 실행
■ 웹페이지 결과
친구들과 스터디를 하나 만들었습니당
바로바로 "일주일에 정해진 개수만큼 블로그를 업로드" 하는 스터디인데요.
어길시 스터디원에게 커피를 돌려야하는 벌칙이 있죠 .. ㅎ ^ ㅎ
개발 과정을 적기 앞서 간단히 스터디원 소개부터 해볼까 합니다~
본인은 leebaek : PS나 개발에 관한 글 3개 작성하기루 했습니다.
기믄지는 hwannow : 현재 우테코 활동 중이라 관련 내용이나 공부한 내용 1개 업로드 하기로 했습니다 ㅋㅋ
( 단, 야무지게 작성해야 함 )
즈즈즈는 Jun-3s : 이번에 복학하는데 코딩은 잘합니다. PS 글 3개 업로드 하기로 했습니다.
델리만준은 뭐 전역부터 하고 같이 할지 고민해본다구 하네요 ㅎㅎ
정해진 결말 아니겠습니까 ~ ?
## leebaek, hwannow : ( -> Jun-3s 고마워 잘 마실게 &^^ )
어떤 글을 업로드했나 ~ 궁금하신 분들을 위해 링크 공유할게요.
hwannow | https://velog.io/@hwannow/posts |
jun-3s | https://jun-3s.tistory.com/ |
■ 전체적인 개발 틀
1. 서버 만들기
2. 데이터베이스 생성
3. 웹 크롤링 - 업로드 개수 확인하는 시스템 개발
4. 웹페이지 개발
친절한 리겔맨이 하나부터 열까지 알려줘서 편하게 ! 아주 편하게 ~ 전체적인 틀을 짤 수 있었답니다. 🤫
❓서버를 어떻게 만들죠 ... ?
학교 수업때 flask 기반 웹페이지는 만들어본 적 있는데 이건 로컬서버로 저만 볼 수 있었거든요 ??
근데 문제는 지금 만드는 웹은 스터디원 전체가 봐야 한다는것 !!
그럴려면 서버가 필요한데, 스터디 하자구 서버까지 사는건 조오금 오바 아닙니까 . 스케일도 작은데 !! 응응
aws에 프리티어로 계정가입을 하고, ( 1년간 무료래요 )
EC2 인스턴스를 생성하였죠.
인스턴스 유형은 t2.micro
OS는 우분투로 선택하였습니다.
EC2란 ?
AWS에서 제공하는 클라우드 기반 가상 서버 서비스입니다.
원래라면 물리서버를 직접 운영해야하지만 서버 유지보수나 하드웨어 관리, 확장성 등등 신경쓸 일이 한두가지가 아니잖아요 ! 그에 반해 클라우드 기반 가상 서버 방식은 필요한 만큼만 서버를 생성하고, 사용한 만큼만 비용을 내면 되기 때문에 효율적이라고 볼 수 있죠.
사실 저도 잘 모르기 때문에 자세한건 포스팅하지 안(못)합니다.
( 지피티한테 물어보는 것을 추천 * _ * - aws ec2 인스터스 생성하는법 )
❓ 데이터 베이스에 어떤 내용을 ?
정말 필요한 것만 넣어 생성하였습니다.
user와 check 반드시 필요하죠오 ~
그리고 date
주차별로 누가 업로드 했는지, 안했는지 기록을 남기고 싶었거든요. !! ( 깃헙 잔디처럼 .. )
마지막으로 id
user, check, date는 모두 중복될 것이기 때문에 따로 고유키를 만들어줬습니다.
id | user | date | check |
고유 번호 | 사용자 이름 | 확인 날짜 | 블로그 업로드 완료 |
int | string | datetime | int |
■ 날짜 크롤링 과정
❓ 웹 크롤링은 어떻게 ... ?
주변 백하는 친구들 보면 웹에서 막 긁어온다 그러자나요.
뭘 어떻게 가져오는거지 ?! 솔직히 좀 궁금했습니다 .
이번 기회로 궁금증이 풀렸네요 ㅎㅎ
이번 개발에서 제일 필요한 정보는
바로 날짜입니다.
업로드 날짜를 통해 해당 스터디원이 일주일에 몇개의 글을 올렸는지 확인할 수 있으니까요. !
이제부터 크롤링하는 방법을 짧게 짧게 설명해볼게요.
1. 먼저, 크롤링할 블로그에 들어가야 합니다.
2. 개발자 도구를 열어 웹페이지의 html 구조를 한번 봐볼까요 ? ( fn + F12 )
- 개발자 도구 상단에 element를 선택할 수 있는 버튼이 있습니다.
- 버튼 클릭 후, 필요한 정보를 선택하면 해당하는 요소의 html 코드를 볼 수 있죠 !
- 회색 배경으로 바뀐 코드를 보면 날짜가 어디 담겨있는지 확인할 수 있습니다.
<span class="txt_date">2025. 2. 23 01:42</span>
3. 이제 크롤링 코드 짜야하는데 막막하다 ~ ( 지피티 시키기 )
- 블로그 링크와 필요한 정보의 태그만 알면 충분히 크롤링 할 수 있습니다.
- node.js 설치 후 js 파일을 하나 생성해줍니다.
- 전체적인 코드는 아래와 같습니다.
- 데이터베이스에 데이터를 넣는 과정은 따로 설명하지 않겠습니다 !
async function fetchLeebaek() {
const { data } = await axios.get('https://leebaek.tistory.com/category');
const $ = cheerio.load(data);
const dates = [];
$('span.txt_date').each((_, el) => dates.push($(el).text().trim()));
const check = dates.slice(0, 3).every(isDateInThisWeek) ? 1 : 0;
await insertCheck('leebaek', check);
console.log('leebaek 데이터 삽입 완료');
}
이제부터 코드 설명을 해보겠습니다 🙂
☑️ axios.get('url') 해당 url의 HTML 데이터를 받아오는 HTTP 요청을 보냅니다.
{ data }는 비구조화 할당 문법으로 axios.get('url')의 응답 객체에서 HTML 문자열만 추출합니다.
const { data } = await axios.get('https://leebaek.tistory.com/category');
axios란 ?
Node.js 및 브라우저 환경에서 HTTP 요청을 보낼 수 있는 JavaScript 라이브러리
웹 서버(API)와 데이터를 주고받을 때 사용하는 라이브러리
☑️ cheerio 라이브러리를 사용하여 가져온 HTML을 파싱합니다.
cheerio.load(data)는 JQuery와 유사한 문법을 사용할 수 있도록 변환해줍니다.
const $ = cheerio.load(data);
Cheerio란 ?
Node.js 에서 HTML을 파싱하고 조작할 수 있는 경량 라이브러리
Cheerio는 실제 웹 브라우저를 실행하지 않고도, HTML 문서를 불러와서 jQuery와 비슷한 문법으로 데이터를 선택하고 조작할 수 있어요.
☑️ 모든 span.txt_date요소에서 날짜를 추출합니다.
.each((_, el) => { . . . } 선택한 요소를 하나씩 순회하면서 el에서 텍스트를 추출합니다.
$(el).text().trim()을 사용해 태그 안의 텍스트(날짜)를 가져온 뒤 앞 뒤 공백을 제거해줍니다.
dates.push()로 dates 배열에 추가해줍니다.
const dates = [];
$('span.txt_date').each((_, el) => dates.push($(el).text().trim()));
☑️ 최근 3개의 날짜가 이번주인지 확인해야 합니다.
dates.slice(0, 3) dates 배열에서 최근 3개의 요소(날짜)를 가져옵니다.
every() 모든 요소가 조건을 만족하면 true를 반환합니다. ( cf: some 는 하나라도 조건을 만족하면 true 반환 )
const check = dates.slice(0, 3).every(isDateInThisWeek) ? 1 : 0;
isDateInThisWeek 함수
function isDateInThisWeek(dateString) {
// "2025. 2. 23. 01:42" → "2025-02-23 01:42" 변환
let formattedDate = dateString
.replace(/\./g, '')
.trim()
.replace(/\s+/g, '-')
.replace(/-(\d)-/g, '-0$1-')
.replace(/-(\d):/, '-0$1:');
// 날짜와 시간 사이의 구분자를 하이픈에서 공백으로 변경
const lastDashIndex = formattedDate.lastIndexOf('-');
if (lastDashIndex !== -1) {
formattedDate = formattedDate.slice(0, lastDashIndex) + ' ' + formattedDate.slice(lastDashIndex + 1);
}
const inputDate = new Date(formattedDate);
if (isNaN(inputDate.getTime())) {
console.error("Invalid date format:", dateString, "->", formattedDate);
return false;
}
const today = new Date();
let firstDay = new Date(today);
// 오늘이 일요일이고 현재 시간이 18시 이전이면, 주의 시작은 지난 일요일 18시로 설정
if (today.getDay() === 0 && today.getHours() < 18) {
firstDay.setDate(today.getDate() - 7);
} else {
firstDay.setDate(today.getDate() - today.getDay());
}
firstDay.setHours(18, 0, 0, 0);
const lastDay = new Date(firstDay);
lastDay.setDate(firstDay.getDate() + 7);
lastDay.setHours(17, 59, 59, 999);
return inputDate >= firstDay && inputDate <= lastDay;
}
■ 정해진 날에 크롤링 코드 실행 : crontab
❓ 정해진 날짜에 자동으로 크롤링 코드가 실행되면 좋겠는데요 !!
☑️ crontab을 사용할겁니다.
그게머에요 ? ( 웅성웅성 ) 🕵🏻♂️
Crontab이란 ?
리눅스에서 특정 시간마다 작업을 자동 실행할 수 있도록 해주는 스케줄러입니다.
예를 들어, 매일 자정에 백업 실행, 5분마다 웹 크롤러 실행 같은 작업을 설정할 수 있습니다.
기본 명령어들을 볼까요 ?
crontab -e # 크론탭 편집 (작업 추가/수정)
crontab -l # 등록된 크론탭 목록 보기
crontab -r # 모든 크론탭 삭제
crontab -u 사용자명 -l # 특정 사용자의 크론탭 목록 보기
작업 등록은 어떤 형식으로 ?
분 시 일 월 요일 실행할_명령어
특수문자
- * → 모든 값 (예: 매일, 매시간 등)
- , → 여러 개 지정 (예: 1,15,30 → 1일, 15일, 30일 실행)
- - → 범위 지정 (예: 9-17 → 9시부터 17시까지 실행)
- / → 주기 실행 (예: */5 → 5분마다 실행)
crontab -e 명령어를 사용해 작업을 등록해볼까요 ?
- 명령어를 치고, i 클릭
- 원하는 줄에 작업 작성
crontab -e
0 18 * * 0,3 node /home/ubuntu/crawler/main.js
저는 main.js가 매주 수요일, 일요일 오후 6시에 작업이 실행되도록 하였습니다.
기타 다른 예시를 보면
0 0 * * * /home/user/backup.sh | 매일 자정에 실행 |
*/10 * * * * /home/user/task.sh | 10분마다 실행 |
0 6 * * 1 /home/user/script.sh | 매주 월요일 아침 6시에 실행 |
자~ 여기까지 하면 크롤링 코드 실행 자동화까지 끄읕 ~ 입니다 !
■ 웹페이지 결과
결과물 보여드릴께요 ㅎ ㅎ ( 지피티 시킴 )
다음 포스팅에서 만나요 ~~