맞춤형 Reddit 검색 도구를 만들었습니다. API? 우리는 그 끔찍한 API가 필요 없어요! (순수 웹 스크래핑 파워!)

발행: (2026년 3월 30일 PM 10:23 GMT+9)
9 분 소요
원문: Dev.to

Source: Dev.to

그때 Reddit이 API를 쓰기 어렵게 만들었을 때 기억하시나요? 전 세계 개발자들이 동시에 진주 목걸이를 움켜쥐듯(좀 더 정확히는 코드베이스를) 놀라워했습니다.
음, 내 다목적 플랫폼 Zlvox에 Reddit 검색 기능이 필요했는데, 솔직히 API 논쟁이나 서드파티 래퍼의 짜증을 겪고 싶지는 않았습니다. 벨벳 로프가 뭐가 필요하겠어요, 그냥… 울타리를 넘을 수 있다면 말이죠?

그래서, 디지털 벽에 부딪힌 모든 이성적인 사람들처럼 나는 MacGyver 모드로 돌입했습니다. API는 잊어버리세요. 화려한 래퍼도 필요 없어요. 나는 덜 걸어본 길, 즉 순수하고 가공되지 않은 웹 스크래핑의 길을 선택했습니다. 인터넷의 위장관에서 직접 데이터를 잡아당기는 느낌이라고 생각하면 됩니다: 순수 요청, 맞춤 파싱, 오직 나와 내 코드, 그리고 엄청난 양의 HTTP.

The Challenge 🧗‍♂️ (Or, “Why I Now Have a Permanent Frown Line”)

만약 레딧 스크래핑을 정중하게 데이터를 요청하는 일이라고 생각한다면, 당신은 아직 한 번도 해보지 않은 겁니다. 이것은 “티 파티”라기보다 “디지털 닌자 미션”에 가깝습니다. 단순히 정적인 HTML 페이지를 가져오는 것이 아니라, 알람을 울리지 않으면서 동적인 콘텐츠의 스파게티 괴물을 풀어내는 작업이었습니다. 밤새도록 저를 괴롭힌 문제들은 다음과 같습니다:

  1. 바운서 우회 – 레딧은 데이터에 대해 벨벳 로프를 설치해 두었습니다. 저는 API 요구사항을 피해가며, 풍성한 검색 결과와 스레드 상세 정보를 훔쳐야 했고, 카페인에 취한 스팸 봇보다 더 빨리 IP가 블랙리스트에 오르는 일을 피해야 했습니다. 레이트 제한? 차단? 그런 건 “극도로 끈질긴 사람들을 위한 방지턱” 정도로 생각하면 됩니다.
  2. 데이터 추출: 위대한 마크업 미로 – 건초더미에서 바늘을 찾는다고 상상해 보세요. 그런데 그 건초더미가 끊임없이 재배열되고 있다면요. 제 파서는 매우 영리한 여우보다도 똑똑해야 했으며, 원시 HTML 정글에서 제목, 서브레딧, 업보트(인터넷 버전의 박수) 및 댓글을 정확히 끌어낼 수 있어야 했습니다.
  3. 성능: 파멸의 로딩 스피너 – 스크래핑은 진정제에 취한 나무늘보보다도 느릴 수 있습니다. 저는 사용자를 끝없는 로딩 스피너의 존재론적 공포에 빠뜨릴 생각이 없었습니다. 백엔드 로직을 최적화하여 결과가 몇 초 안에 표시되도록 해야 했습니다.

How I Built It 🛠️ (Or, “My Glorious Crusade Against Bloat”)

풀스택 개발자로서 고백하자면, 저는 통제광입니다. 코드가 어떻게 동작하는지 한 줄 한 줄 정확히 알고 싶어 하거든요. 그래서 이렇게 맞춤형 접근 방식을 택했습니다.

The Backend (My Digital Data Thief)

공식 Reddit JSON 엔드포인트(서버‑사이드 요청 시 차단되는 경우가 많음)를 직접 호출하는 대신, DuckDuckGo의 HTML 검색을 활용하는 지능형 프록시를 만들었습니다. 이를 통해 DDG의 고급 날짜‑필터링 로직(예: df=d는 지난 24시간) 을 “검색‑엔진 레이어”로 사용하고, 스크래퍼가 데이터를 잡아오기 전에 필터링할 수 있습니다.

Core “Magic Trick”

'd', 'week' => 'w', 'month' => 'm', 'year' => 'y'];
$df = $dateMap[$timeFilter] ?? '';

// 2. Construct the search URL (specifically targeting reddit.com)
$url = 'https://html.duckduckgo.com/html/?q=' .
       urlencode("site:reddit.com $query") .
       "&df=$df";

// 3. Simple cURL request with a realistic User-Agent to mimic a browser
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt(
    $ch,
    CURLOPT_USERAGENT,
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36'
);
$html = curl_exec($ch);
curl_close($ch);

// 4. THE MAGIC: Extract Reddit links and metadata using Regex
//    We grab the href, then look for stats like upvotes/comments in the snippets
preg_match_all('/href=["\'](\/\/[^"\']+)["\']/', $html, $links);
preg_match_all('/(.*?)/si', $html, $snippets);

$results = [];
foreach ($links[1] as $i => $url) {
    $snippet = strip_tags($snippets[1][$i] ?? '');

    // Extracting Upvotes and Comments from the text snippet
    $upvotes = 0;
    if (preg_match('/(\d+)\s+upvotes?/i', $snippet, $m)) {
        $upvotes = (int)$m[1];
    }

    $results[] = [
        'url'     => $url,
        'upvotes' => $upvotes,
        'snippet' => substr($snippet, 0, 150) . '...',
    ];
}

return $results;
?>

Data Parsing: Taming the Wild West

디지털 스파이가 원시 데이터를 가져오면, 코드는 마치 세심한 사서처럼 작동합니다. 혼란스러운 데이터를 파싱하고, 디지털 먼지를 털어내며, 모든 것을 깔끔한 JSON 형태로 정리합니다. 원시 데이터라도 보기 좋게 정리될 자격이 있거든요!

The Frontend (My One‑Man Style Army)

전체 UI는 100 % 커스텀 CSS로만 구현했습니다—Bootstrap도, Tailwind도, “버튼 하나에 500 KB를 추가하자” 같은 서드‑파티 라이브러리도 없습니다. 순수하고 가벼운 CSS만 사용했죠. 마치 데이터에 맞춘 맞춤 정장처럼, 최고의 성능, 제로 부피, 그리고 “내 방식대로 만들었다”는 느낌을 줍니다!

결과 🎯 (또는, “보라, 내 API‑무료 걸작!”)

대단원의 피날레? 레딧 검색 도구가 번개처럼 빠르고 정확해서 API 제한을 눈감아 버립니다. 쿼리를 입력하면 백엔드 스크래퍼가 디지털 주술을 수행하고, 맞춤형 프론트엔드가 화려하게 결과를 보여줍니다.

실시간으로 사용해 보기:


What’s Next? (Or, “More Digital Shenanigans”)

이 모험은 꽤 교육적이었어요. 인터넷이 양파보다 더 많은 층을 가지고 있다는 걸 알게 되었고, 저는 그걸 하나씩 벗겨내고 있답니다. 다음은? 훨씬 더 고급 필터링 옵션을 추가하는 것—디지털 우주를 자유롭게 필터링하는 힘을 누가 싫어하겠어요?

Your Turn

그러니 솔직히 말해보세요! 주요 플랫폼을 위한 웹 스크래핑을 시도해 본 적 있나요? 어떤 디지털 드래곤을 물리쳤고, 어떤 도전이 인생 선택을 의심하게 만들었나요? 댓글에서 함께 축하(또는 위로)해요! 👇


Tags: webdev php scraping javascript

#productivity
0 조회
Back to Blog

관련 글

더 보기 »