파이썬도, 설치도 없습니다. 구글 계정 하나로 웹페이지의 데이터를 표로 가져오는 방법을 4단계로 실습합니다. 크롤링은 구글 서버가 대신 수행하므로 내 컴퓨터에 아무것도 깔지 않습니다.
실습 대상은 DataForge가 직접 운영하는 연습용 페이지라 마음껏 시도해도 됩니다.
준비 실습 대상 페이지 로그인 없이 열립니다
연습용 페이지 ● 실습 허용
  • 생산 현황 진짜 <table>로 된 표 — 1단계용 TABLE
  • 부품 카탈로그 카드 12개 (제품명·가격·분류·제조사) — 2단계용 12건
  • 공지·뉴스 목록 10개 (제목·작성자·날짜) — 2단계용 10건
  • 센서 API JSON으로 바로 주는 주소 — 4단계용 JSON
먼저 한 번 눌러보세요. 페이지가 어떻게 생겼는지 눈으로 본 다음에 시트로 가져와야 "무엇을 가져온 것인지"가 이해됩니다. 특히 생산 현황은 표로 보이고, 부품 카탈로그는 표처럼 보이지만 실은 카드라는 점을 기억해 두세요. 1단계와 2단계가 갈리는 지점입니다.
STEP 1 표가 있는 페이지 — IMPORTHTML 수식 1줄 · 3분

구글 시트를 새로 열고 A1 칸에 아래 수식을 그대로 붙여넣으세요. 잠시 뒤 생산 현황 표가 통째로 들어옵니다.

GOOGLE SHEETS
=IMPORTHTML("https://dataforge.ai.kr/factory_lab/production/", "table", 1)
세 조각으로 읽습니다. 주소 — 어느 페이지에서 / "table" — 표를 (목록이면 "list") / 1 — 그 페이지의 몇 번째 표인지.
표가 여러 개인 페이지라면 숫자를 2, 3으로 바꿔 가며 찾습니다.

이제 같은 수식의 주소만 부품 카탈로그로 바꿔서 넣어 보세요. #N/A 가 뜹니다. 실패한 게 아니라, 그 페이지에는 <table>이 없기 때문입니다. 요즘 웹페이지 대부분이 이렇습니다. 그래서 2단계가 필요합니다.

STEP 2 표가 없는 페이지 — IMPORTXML 원하는 항목만 골라 오기
수식 생성기

가져올 페이지와 항목을 고르면 수식이 만들어집니다. 복사해서 시트에 붙여넣으세요. 직접 타이핑할 필요는 없습니다 — 먼저 되는 걸 보고, 원리는 그다음에 봅니다.

대상 페이지
가져올 항목
구글 시트 수식
이 수식이 가리키는 것
선택자 치트시트

수식 안의 //div[@class='cc-name'] 같은 부분이 "페이지에서 무엇을 집을지"를 가리킵니다. 페이지를 만든 사람이 각 항목에 붙여 둔 이름표(class)를 쓰는 것입니다.

페이지항목이름표(class)XPath
이름표는 어떻게 알아내나요? 페이지에서 원하는 값 위에 마우스 우클릭 → 검사를 누르면 개발자 도구가 열리고, 그 값에 해당하는 줄이 파랗게 표시됩니다. 거기 적힌 class="..."가 이름표입니다. 위 표는 우리 연습 페이지의 이름표를 미리 정리해 둔 것이니, 먼저 표로 성공한 뒤에 직접 찾아보세요.
STEP 3 수식으로 안 될 때 — Apps Script 한 번 심어두면 계속 씀

IMPORTXML은 편하지만 느리고, 가끔 로딩 중...에서 멈춥니다. 아래 코드를 시트에 한 번 심어두면 내 전용 수식이 생깁니다. 코드는 강사가 한 번 붙여넣는 것이고, 교육생은 수식만 씁니다.

  1. 구글 시트 상단 메뉴 확장 프로그램 → Apps Script 클릭
  2. 편집기에 있던 function myFunction() {}모두 지우기
  3. 아래 코드를 붙여넣기
  4. 💾 저장 버튼 클릭 (권한을 물으면 허용)
  5. 시트로 돌아와 =긁기(...) 수식 사용
APPS SCRIPT
/**
 * DataForge — 구글 시트 크롤링 도우미
 *   =긁기("주소", "이름표")       웹페이지에서 값 가져오기
 *   =API표("주소", "배열이름")     JSON API를 표로 가져오기
 */

function 긁기(url, 이름표) {
  if (!url || !이름표) return [['주소와 이름표를 모두 넣어주세요']];

  var res = UrlFetchApp.fetch(url, {
    muteHttpExceptions: true,
    followRedirects: true
  });
  if (res.getResponseCode() !== 200) {
    return [['가져오지 못했습니다 (응답코드 ' + res.getResponseCode() + ')']];
  }

  var html = res.getContentText();          // 옛 한글 사이트면 getContentText('EUC-KR')
  var 패턴 = new RegExp('class\\s*=\\s*"[^"]*\\b' + 이름표 + '\\b[^"]*"[^>]*>', 'i');
  var 조각 = html.split(패턴);

  var 결과 = [];
  for (var i = 1; i < 조각.length; i++) {
    var t = 조각[i].split(/<\/[a-z]/i)[0];   // 첫 닫는 태그 앞까지만
    t = t.replace(/<[^>]*>/g, ' ');         // 남은 태그 제거
    t = 정리(t);
    if (t) 결과.push([t]);
  }
  return 결과.length ? 결과 : [['찾지 못했습니다 — 이름표를 확인하세요']];
}

function API표(url, 배열이름) {
  var res = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
  var data = JSON.parse(res.getContentText());
  var arr  = 배열이름 ? data[배열이름] : data;

  if (!Array.isArray(arr) || arr.length === 0) return [['배열을 찾지 못했습니다']];

  var 열이름 = Object.keys(arr[0]);
  var 표 = [열이름];
  for (var i = 0; i < arr.length; i++) {
    var 행 = [];
    for (var j = 0; j < 열이름.length; j++) 행.push(arr[i][열이름[j]]);
    표.push(행);
  }
  return 표;
}

function 정리(s) {
  return s.replace(/&nbsp;/g, ' ')
          .replace(/&lt;/g, '<').replace(/&gt;/g, '>')
          .replace(/&quot;/g, '"').replace(/&#0?39;/g, "'")
          .replace(/&amp;/g, '&')
          .replace(/\s+/g, ' ')
          .trim();
}
심고 나면 이렇게 씁니다
수식결과
=긁기("https://dataforge.ai.kr/factory_lab/catalog/", "cc-name") 제품명 12개
=긁기("https://dataforge.ai.kr/factory_lab/catalog/", "cc-price") 가격 12개
=긁기("https://dataforge.ai.kr/factory_lab/news/", "ni-title") 뉴스 제목 10개
이 코드가 하는 일은 단 두 가지입니다. ① 구글 서버에게 "이 주소의 HTML을 가져와" 시키고 ② 그 안에서 이름표가 붙은 값만 골라냅니다. 외부 라이브러리를 쓰지 않아 남의 코드가 사라져서 수업이 깨질 일이 없습니다. 대신 태그가 한 겹까지 중첩된 단순한 항목까지만 처리합니다 — 연습 페이지는 모두 여기에 해당합니다.
STEP 4 사실 더 좋은 길 — API 긁지 않고 받아오기

크롤링은 남의 집 창문으로 들여다보는 것에 가깝습니다. 그런데 어떤 사이트는 현관문을 열어두고 "데이터 필요하면 여기서 가져가세요" 하고 알려줍니다. 그게 API입니다. 화면이 아니라 데이터를 직접 주기 때문에 훨씬 정확하고, 사이트 디자인이 바뀌어도 안 깨집니다.

센서 API 주소를 브라우저에서 그냥 열어보세요. 화면 대신 데이터가 그대로 보입니다. 이걸 시트로 가져오면:

GOOGLE SHEETS
=API표("https://dataforge.ai.kr/factory_lab/sensor/api.php", "sensors")
열 이름까지 자동으로 붙습니다. sensor_code · name · location · value · unit · status … 크롤링에서는 이름표를 하나하나 찾아야 했던 걸, API는 처음부터 이름을 달아서 줍니다.
실무에서는 공공데이터포털처럼 API를 제공하는 곳이 있는지 먼저 확인하는 게 순서입니다. 크롤링은 API가 없을 때의 차선책입니다.
실습 미션 — 수식을 직접 만들어 보기 채점은 이 페이지에서
맞힌 개수
0 / 5
채점은 수식의 모양을 봅니다 — 함수 이름, 주소, 이름표가 맞는지. 띄어쓰기나 따옴표 종류가 조금 달라도 통과하니 편하게 넣어보세요.
주의 크롤링 예절과 선
여기서 배운 걸 아무 사이트에나 쓰면 안 됩니다. 기술적으로 가능한 것과 해도 되는 것은 다릅니다.
  • 이용약관을 먼저 봅니다. 대부분의 상용 사이트는 자동 수집을 약관에서 금지합니다.
  • 회원가입·로그인이 필요한 데이터는 건드리지 않습니다. 담장을 넘는 것과 같습니다.
  • 개인정보는 수집하지 않습니다. 공개돼 있어도 모아서 저장하는 순간 책임이 생깁니다.
  • 짧은 간격으로 반복 요청하지 않습니다. 상대 서버에는 공격과 구분되지 않습니다.
  • robots.txt를 확인합니다. 주소 뒤에 /robots.txt를 붙이면 그 사이트가 "여기는 긁지 말아 달라"고 적어둔 문서가 나옵니다.
  • API가 있으면 API를 씁니다. 4단계가 그 이야기입니다.
이 페이지의 연습 대상은 DataForge가 직접 운영합니다. 마음껏 시도해도 되는 이유는 실력이 아니라 허락 때문입니다. 실무에서 대상 사이트를 고를 때도 순서는 똑같습니다 — 허락부터 확인하세요.