Computer >> 컴퓨터 >  >> 소프트웨어 >> 브라우저

효율적인 웹 스크래핑: 브라우저 콘솔로 JavaScript 데이터 추출하고 파일로 저장하기

얼마 전 필자는 한 사이트의 링크를 전부 수집한 뒤, 그 링크들을 이용해 Selenium이나 Puppeteer로 각 페이지의 세부 데이터를 크롤링해야 하는 작업을 진행했습니다. 그런데 사이트 구조가 다소 특이해서 바로 Selenium과 Node.js로 시작하기 어려웠고, 안타깝게도 데이터 양도 방대했습니다. 결국 모든 링크를 먼저 빠르게 수집한 후, 각 페이지의 상세 크롤링으로 넘겨주는 방식을 고안해야 했습니다.

그 과정에서 알게 된 것이 바로 브라우저 Console API를 활용하는 기술입니다. 별도의 환경 설정 없이 어떤 웹사이트에서든 사용할 수 있으며, 순수 JavaScript이기 때문입니다.

지금부터 기술적인 내용을 하나씩 살펴보겠습니다.

전체 흐름 한눈에 보기

페이지의 모든 링크를 크롤링하기 위해 콘솔에 짧은 JavaScript 코드를 작성했습니다. 이 코드는 페이지네이션까지 처리하면서 약 1~2시간에 걸쳐 모든 링크를 수집하고, 결과를 json 파일로 저장합니다.

여기서 유의할 점이 있습니다. 대상 웹사이트가 싱글 페이지 애플리케이션(SPA)처럼 동작해야 한다는 것입니다. 그렇지 않으면 여러 페이지를 크롤링하려 할 때 페이지가 새로고침되면서 콘솔에 입력한 코드가 사라져 버립니다.

Medium은 일부 상황에서 페이지를 새로고침하지 않습니다. 지금은 Medium의 한 글을 크롤링하고, 수집한 데이터를 콘솔에서 자동으로 파일로 저장해 보겠습니다.

본격적으로 들어가기 전에 최종 실행 결과 데모를 먼저 확인해 보세요.

1단계: 브라우저에서 콘솔 객체 인스턴스 가져오기

// 새 데이터를 로깅하기 전에 콘솔을 정리하는 Console API
console.API;

if (typeof console._commandLineAPI !== 'undefined') {
  console.API = console._commandLineAPI; // Chrome
} else if (typeof console._inspectorCommandLineAPI !== 'undefined') {
  console.API = console._inspectorCommandLineAPI; // Safari
} else if (typeof console.clear !== 'undefined') {
  console.API = console;
}

이 코드는 현재 사용 중인 브라우저에 맞는 콘솔 객체 인스턴스를 가져오는 역할을 합니다. 굳이 분기 처리가 필요 없다면, 자신이 사용하는 브라우저에 맞는 인스턴스만 직접 할당해도 무방합니다.

예를 들어 Chrome을 사용한다면 아래 코드만으로 충분합니다.

if (typeof console._commandLineAPI !== 'undefined') {
  console.API = console._commandLineAPI; // Chrome
}

2단계: 주니어(Junior) 헬퍼 함수 정의하기

브라우저에서 Medium 글 하나를 열어 두었다고 가정하겠습니다. 코드의 6~12번째 줄은 DOM 요소의 속성을 정의하는 부분으로, 각각 글 제목, 클랩(박수) 수, 사용자 이름, 프로필 이미지 URL, 프로필 설명, 글을 읽는 데 걸리는 시간을 추출하는 데 사용됩니다.

이것이 이 글에서 보여드릴 기본 요소들입니다. 필요에 따라 글 안의 링크, 모든 이미지, 임베드 링크 등의 요소를 추가로 추출하도록 확장할 수도 있습니다.

3단계: 시니어(Senior) 헬퍼 함수 정의하기 — 핵심 함수

페이지의 여러 요소를 크롤링하면서 그 값들은 하나의 컬렉션에 저장되고, 이 컬렉션이 메인 함수로 전달됩니다.

console.save라는 이름의 함수를 정의합니다. 이 함수의 역할은 전달받은 데이터를 CSV 또는 JSON 파일로 덤프하는 것입니다.

함수는 전달받은 데이터로 Blob 객체를 생성합니다. Blob(Binary Large Object)은 불변의 원시 데이터를 파일처럼 다룰 수 있게 해주는 객체로, 반드시 JavaScript 네이티브 형식일 필요가 없는 데이터를 표현합니다.

생성된 Blob은 <a> 태그에 연결되고, 이 태그에 클릭 이벤트를 발생시켜 파일 다운로드를 실행합니다.

아래는 작은 array를 데이터로 전달해 console.save를 실행해 본 간단한 데모입니다.

지금까지 만든 코드 조각들을 모두 합치면 다음 세 가지가 완성됩니다.

  1. Console API 인스턴스
  2. 요소를 추출하는 헬퍼 함수
  3. 파일을 생성하는 Console Save 함수

이제 브라우저에서 console.save()를 실행해 데이터를 파일로 저장해 보겠습니다. Medium의 글 페이지로 이동한 뒤, 브라우저 콘솔에서 이 코드를 실행하면 됩니다.

응용: 여러 글 한 번에 크롤링하기

앞선 데모는 단일 페이지에서 데이터를 추출하는 예시였지만, 같은 코드를 응용하면 출판사(publisher) 홈 페이지에서 여러 글을 한꺼번에 크롤링할 수 있습니다. freeCodeCamp를 예로 들면, 한 글에서 다른 글로 이동한 뒤 브라우저의 뒤로 가기 버튼을 눌러도 페이지가 새로고침되지 않고 출판사 홈으로 돌아올 수 있습니다.

출판사 홈 페이지에서 여러 글을 추출하기 위해 필요한 최소한의 코드를 준비했다면, 실제로 여러 글에서 프로필 설명을 가져오는 모습을 직접 확인해 보세요.

이런 종류의 작업이라면, 데이터를 수집한 후 console.save 함수에 전달하여 파일로 저장하기만 하면 됩니다.

console.save 함수는 콘솔 코드에 빠르게 붙여 사용할 수 있으며, 데이터를 손쉽게 파일로 내보내는 데 도움이 됩니다. 물론 반드시 콘솔로 스크래핑해야 한다는 뜻은 아니지만, CSS 선택자로 DOM을 다루는 일에 이미 익숙한 개발자라면 때때로 이 방법이 훨씬 빠른 접근 방식이 될 수 있습니다.

전체 코드는 GitHub에서 다운로드할 수 있습니다.

이 글을 끝까지 읽어 주셔서 감사합니다! 복잡한 설정 없이 빠르게 데이터를 스크래핑할 수 있는 아이디어를 얻으셨기를 바랍니다. 마음에 드셨다면 박수(클랩) 버튼을 눌러 주세요. 궁금한 점이 있다면 praveend806 [at] gmail [dot] com으로 메일을 보내 주세요.

콘솔을 더 깊이 알고 싶다면: 참고 자료

  • Using the Console | Tools for Web Developers | Google Developers — Chrome DevTools JavaScript 콘솔을 활용하는 방법을 학습할 수 있습니다. (developers.google.com)
  • Browser Console — Browser Console은 Web Console과 비슷하지만, 단일 콘텐츠 탭이 아닌 브라우저 전체에 적용됩니다. (developer.mozilla.org)
  • Blob — Blob 객체는 불변의 원시 데이터를 파일처럼 표현하는 객체입니다. (developer.mozilla.org)

무료로 코딩을 배워 보세요. freeCodeCamp의 오픈소스 커리큘럼은 이미 4만 명 이상의 사람들이 개발자로 취업하는 데 도움을 주었습니다.