How to Implement Web Scraping: Claude Code 활용 가이드
implement web scraping: Claude Code 활용. 실용적인 코드 예시와 단계별 가이드를 포함합니다.
WebスクレイピングをClaude Code로 효율화하기
Webスクレイピングは、데이터収集や監視、競合分析などに활용される技術です。Claude Code를 활용하면 HTML解析から데이터整形まで一貫したスクレイピングスクリプトを短시간で구축할 수 있습니다。
Cheerioで静的페이지をスクレイピング
JavaScript렌더링が不要な페이지にはCheerioが最適です。
> Cheerioでニュースサイトの글제목とリンクを취득するスクリプトを作って。
> リトライ機能とレート制限も入れて。
import * as cheerio from "cheerio";
interface Article {
title: string;
url: string;
date?: string;
}
async function fetchWithRetry(
url: string,
retries = 3,
delay = 1000
): Promise<string> {
for (let i = 0; i < retries; i++) {
try {
const res = await fetch(url, {
headers: {
"User-Agent": "Mozilla/5.0 (compatible; MyBot/1.0)",
},
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.text();
} catch (error) {
if (i === retries - 1) throw error;
console.log(`リトライ ${i + 1}/${retries}...`);
await new Promise((r) => setTimeout(r, delay * (i + 1)));
}
}
throw new Error("Unreachable");
}
async function scrapeArticles(url: string): Promise<Article[]> {
const html = await fetchWithRetry(url);
const $ = cheerio.load(html);
const articles: Article[] = [];
$("article, .article, .post").each((_, element) => {
const titleEl = $(element).find("h2 a, h3 a, .title a").first();
const title = titleEl.text().trim();
const href = titleEl.attr("href");
const date = $(element).find("time, .date").first().text().trim();
if (title && href) {
articles.push({
title,
url: new URL(href, url).toString(),
date: date || undefined,
});
}
});
return articles;
}
Puppeteerで動的페이지をスクレイピング
SPAやJavaScriptで描画される페이지にはPuppeteer를 사용합니다。
import puppeteer from "puppeteer";
interface ProductData {
name: string;
price: number;
rating: number;
imageUrl: string;
}
async function scrapeDynamicPage(url: string): Promise<ProductData[]> {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
// 不要なリソースをブロックして高速化
await page.setRequestInterception(true);
page.on("request", (req) => {
const type = req.resourceType();
if (["image", "stylesheet", "font"].includes(type)) {
req.abort();
} else {
req.continue();
}
});
await page.goto(url, { waitUntil: "networkidle2" });
// 無限스크롤で全데이터を読み込む
let previousHeight = 0;
while (true) {
const currentHeight = await page.evaluate(() => document.body.scrollHeight);
if (currentHeight === previousHeight) break;
previousHeight = currentHeight;
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await new Promise((r) => setTimeout(r, 1500));
}
const products = await page.evaluate(() => {
const items = document.querySelectorAll(".product-card");
return Array.from(items).map((item) => ({
name: item.querySelector(".product-name")?.textContent?.trim() || "",
price: parseFloat(
item.querySelector(".price")?.textContent?.replace(/[^0-9.]/g, "") || "0"
),
rating: parseFloat(
item.querySelector(".rating")?.getAttribute("data-value") || "0"
),
imageUrl: item.querySelector("img")?.getAttribute("src") || "",
}));
});
await browser.close();
return products;
}
데이터の저장と構造化
취득した데이터をJSON、CSV形式で저장します。
import fs from "fs/promises";
async function saveAsJson(data: unknown[], filePath: string) {
await fs.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
console.log(`${filePath} に ${(data as any[]).length}件を保存しました`);
}
function toCsvString(data: Record<string, unknown>[]): string {
if (data.length === 0) return "";
const headers = Object.keys(data[0]);
const rows = data.map((row) =>
headers.map((h) => {
const val = String(row[h] ?? "");
return val.includes(",") || val.includes('"')
? `"${val.replace(/"/g, '""')}"`
: val;
}).join(",")
);
return [headers.join(","), ...rows].join("\n");
}
async function saveAsCsv(data: Record<string, unknown>[], filePath: string) {
const csv = toCsvString(data);
await fs.writeFile(filePath, csv, "utf-8");
console.log(`${filePath} に保存しました`);
}
定期実行とスケジューリング
import cron from "node-cron";
function startScheduledScraping() {
// 毎日9時に実行
cron.schedule("0 9 * * *", async () => {
console.log(`[${new Date().toISOString()}] スクレイピング開始`);
try {
const articles = await scrapeArticles("https://example.com/news");
const timestamp = new Date().toISOString().split("T")[0];
await saveAsJson(articles, `./data/articles-${timestamp}.json`);
} catch (error) {
console.error("スクレイピングエラー:", error);
}
});
console.log("スケジュール設定完了(毎日9:00実行)");
}
倫理的な配慮
Webスクレイピングを行う際は、다음의点に주의して주세요。
- robots.txtを확인し、クローリングが허가されているか확인する
- 요청間隔を적절하게設けて서버に負荷をかけない
- 利用規約を확인し、スクレイピングが禁止されていないか확인する
- 취득した데이터の著作権と利用目的を考慮する
Markdown形式で데이터を加工する方法はMarkdown処理・変換를 참고하세요.CLIツール로서구축する場合はCLIツール개발도 확인하세요.
정리
Claude Code를 활용하면 静的・動的페이지のスクレイピング、데이터整形、定期実行まで含めたスクレイピングシステムを短시간で구축할 수 있습니다。セレクタの指定や데이터変換も自然言語で指示する만으로す。
자세한 내용은Claude Code공식 문서를 참고하세요.
Claude Code 워크플로우를 한 단계 업그레이드하세요
지금 바로 Claude Code에 복사해 쓸 수 있는 검증된 프롬프트 템플릿 50선.
이 글을 작성한 사람
Masa
Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.
관련 글
Claude Code로 리팩토링을 자동화하는 방법
Claude Code를 활용해 코드 리팩토링을 효율적으로 자동화하는 방법을 알아봅니다. 실전 프롬프트와 구체적인 리팩토링 패턴을 소개합니다.
Claude Code로 사이드 프로젝트 개발 속도를 극대화하는 방법 [예제 포함]
Claude Code를 활용해 개인 프로젝트 개발 속도를 획기적으로 높이는 방법을 알아봅니다. 실전 예제와 아이디어부터 배포까지의 워크플로를 포함합니다.
Complete CORS Configuration Guide: Claude Code 활용 가이드
complete cors configuration guide: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.