본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 06. 05:26

정규 표현식(Regex) 작성을 멈추고 AI에게 지저분한 데이터를 파싱하게 만든 방법

요약

정규 표현식과 CSS 셀렉터를 이용한 전통적인 웹 스크래핑의 한계를 LLM을 활용한 데이터 추출 방식으로 해결한 사례를 소개합니다. HTML을 직접 파싱하는 대신 텍스트로 변환하여 LLM에 전달함으로써 구조화된 JSON 데이터를 효율적으로 얻는 방법을 다룹니다.

핵심 포인트

  • 정규 표현식 대신 LLM을 사용하여 비정형 데이터 파싱
  • readability 라이브러리로 노이즈를 제거한 텍스트 전달
  • gpt-4o-mini를 활용한 저비용·고효율 구조화 데이터 추출
  • 다양한 HTML 구조와 라벨 변형에 유연하게 대응 가능

저는 수십 개의 니치(niche) 웹사이트에서 채용 공고를 수집하는 사이드 프로젝트를 진행해 왔습니다. 각 사이트는 저마다의 HTML 구조, 일관성 없는 CSS 클래스, 그리고 때로는 정말 혼란스러운 마크업(markup)을 가지고 있습니다. 몇 달 동안 저는 BeautifulSoup, lxml, CSS 셀렉터(selectors), 그리고 결국에는 마치 선 노이즈(line noise)처럼 보이는 산더미 같은 정규 표현식(regex) 패턴들을 사용하는 고전적인 스크래핑 도구 세트를 시도했습니다.

그것은 작동했습니다. 한 사이트가 템플릿을 업데이트하여 제가 정성스럽게 만든 셀렉터들이 깨지기 전까지는 말이죠. 또다시 말입니다. 저는 실제로 데이터를 사용하는 시간보다 스크래퍼(scraper)를 유지보수하는 데 더 많은 시간을 쓰고 있는 저 자신을 발견했습니다. 저는 다른 접근 방식이 필요했습니다.

효과가 없었던 것들

저의 첫 번째 본능은 패턴에 더 집중하는 것이었습니다. 저는 "Job Title:" 뒤에 텍스트가 오고, 그 뒤에 "Location:" 등이 오는 식의 정규 표현식(regex)을 작성했습니다. 하지만 많은 사이트가 라벨을 사용하지 않거나, 데이터를 테이블(table) 안에 중첩시키거나, 순서를 망가뜨리는 숨겨진 span 태그를 삽입하곤 했습니다.

그다음에는 시각적 유사성(visual similarity)을 시도했습니다. 스크린샷에 OCR을 사용하는 방식이었죠. 그것은 느리고, 비용이 많이 들며, 열(column)이 여러 개인 경우에는 부정확했습니다.

개체명 인식(named entity extraction)을 위해 작은 모델을 학습시키는 것도 고려해 보았지만, 라벨링된 데이터셋(labeled dataset)이 없었고 사이트들은 계속해서 변했습니다. 저에게는 단순히 고정된 위치가 아니라 문맥(context)을 이해할 수 있는 무언가가 필요했습니다.

돌파구: LLM이 페이지를 읽게 하기

LLM(대규모 언어 모델)은 좋은 프롬프트(prompt)를 제공할 때, 비정형 텍스트에서 구조화된 정보를 추출하는 데 놀라울 정도로 뛰어납니다. HTML을 파싱하려고 노력하는 대신, 저는 페이지를 일반 텍스트로 렌더링하고(readability 라이브러리를 사용하여 내비게이션과 광고를 제거), 그 텍스트를 명확한 지침과 함께 AI 모델에 전달하기로 결정했습니다: "이 텍스트에서 채용 공고를 추출하세요. 각 공고에 대해 제목(title), 회사(company), 위치(location), 급여(salary), 설명(description)을 포함하는 JSON 객체를 반환하세요."

제가 최종적으로 도달한 핵심 기술은 다음과 같습니다:

import json
from openai import OpenAI  # 또는 호환 가능한 모든 API
import requests
...

이 코드는 다음을 포함하는 프롬프트(prompt)를 전송합니다:

  • 필드 정의가 포함된 명확한 스키마 (schema)
  • 누락된 필드에 대한 기본값 (Default values)
  • 출력 예시
  • 실제 페이지 텍스트 (일부 생략)

저는 gpt-4o-mini를 사용했는데, 가격이 저렴하고 빠르기 때문입니다. 입력 토큰 100만 개당 약 0.15달러 수준입니다. 3,000 토큰 정도 되는 일반적인 채용 공고 페이지의 경우, 페이지당 1센트도 되지 않는 비용이 듭니다.

잘 작동했던 부분

LLM 접근 방식은 다음 사항들을 처리할 수 있습니다:

  • 다양한 HTML 구조 (리스트, 테이블, div)
  • 누락되었거나 부분적인 데이터 (기본값을 추론함)
  • 라벨링의 변형 ("Location:", "Based in", "Where")
  • 여러 공고가 있는 페이지 (모든 채용 정보를 한 번에 추출)

저는 가공되지 않은 HTML이 아닌, 깨끗하고 읽기 쉬운 텍스트를 보내기 때문에 모델이 마크업(markup) 때문에 혼란을 겪지 않습니다. readability 라이브러리(python-readability)는 주요 콘텐츠를 추출하는 데 탁월한 성능을 보여줍니다. 저는 이 라이브러리를 수년간 사용해 왔으며, 대부분의 뉴스 및 리스팅 사이트에서 잘 작동합니다.

트레이드오프(Trade-offs)와 한계점

솔직히 말씀드리면, 이것이 만능 해결책(silver bullet)은 아닙니다. 다음과 같은 부분에서 문제가 발생할 수 있습니다:

  • 비용 (Cost): 토큰 100만 개당 0.15달러라 하더라도, 하루에 1,000페이지를 처리하면 약 5달러가 듭니다. 대량의 스크래퍼(scraper)를 운영한다면 이 비용은 점점 커집니다.
  • 지연 시간 (Latency): 각 요청은 1~3초가 소요됩니다. 100페이지를 처리하려면 몇 분이 걸리는데, 이는 실시간 대시보드에는 적합하지 않습니다.
  • 환각 (Hallucinations): 페이지 내용이 모호할 때 모델이 가끔 급여나 회사 이름을 지어내기도 합니다. 저는 항상 중요한 필드(예: 회사 이름이 알려진 목록에 존재하는지 확인)를 검증합니다.
  • 토큰 제한 (Token limits): 페이지가 길면 내용이 잘립니다. 저는 이를 여러 요청으로 나누거나, 더 큰 컨텍스트를 가진 모델(gpt-4o-128k)을 사용합니다.
  • 프롬프트 엔지니어링 (Prompt engineering): 예시와 지침이 매우 중요합니다. 문구의 작은 변화만으로도 필드가 누락될 수 있습니다. 저는 규모를 확장하기 전에 5~10개의 테스트 페이지로 반복 작업을 수행합니다.

이 접근 방식을 사용하지 말아야 할 때

  • 거의 완벽한 정확도가 필요한 경우(예: 금융 데이터), XPath + 검증(validation)을 사용하는 전통적인 추출 방식이 여전히 더 낫습니다.
  • 구조가 잘 정의된 사이트 한두 곳을 스크래핑하는 경우라면, 정규 표현식(regex)이 더 간단하고 비용도 들지 않습니다.
  • 페이지 수가 수천 개 수준이고 예산이 빠듯하다면, AI 비용이 부담될 수 있습니다.

다음에 제가 다르게 시도할 점들

  1. 결과 캐싱 (Cache results): 이제 각 페이지의 텍스트와 AI 출력값을 로컬 데이터베이스에 저장합니다. 페이지가 변경되지 않았다면 다시 쿼리하지 않습니다.
  2. 단순한 페이지에는 더 저렴한 모델 사용: 레이아웃이 단순한 사이트의 경우, gpt-4o-mini(또는 Llama 3.2와 같은 더 작은 로컬 모델)로 전환합니다.
  3. 검증 레이어 (Validation layer) 추가: 추출 후 간단한 체크를 수행합니다. 예를 들어, "급여 문자열에 달러 기호($)가 포함되어 있는가?"와 같은 방식입니다. 신뢰도가 낮은 출력값은 수동 검토를 위해 플래그를 지정합니다.
  4. 전용 추출 API 고려: 일부 서비스(예: ai.interwestinfo.com URL의 기반이 되는 서비스)는 바로 이러한 사용 사례를 위해 구축되었으며, 구조화된 데이터에 대해 더 나은 속도와 정확도를 제공할 수 있습니다.

마치며

정규 표현식(Regex)은 항상 제 도구 상자에서 자리를 차지할 것입니다. 빠르고, 결정론적(deterministic)이며, 디버깅이 가능하기 때문입니다. 하지만 지저분하고 예측 불가능한 웹 페이지들이 길게 늘어진 '롱테일(long tail)' 영역에 대해서는, 탄탄한 프롬프트(prompt)와 함께 텍스트를 LLM에 전달하는 것이 실용적인 대안이 됩니다. 이 방식은 저에게 셀렉터(selector) 유지보수에 들어갈 몇 주간의 시간을 아껴주었습니다.

이 기술은 채용 공고에만 국한되지 않습니다. 제품 사양, 이벤트 상세 정보 또는 기타 모든 반구조화된(semi-structured) 콘텐츠를 추출하는 데 응용할 수 있습니다. 다만 출력값을 검증하고 비용을 계속 모니터링해야 한다는 점을 기억하세요.

여러분은 어떠신가요? 여러분은 언제 전통적인 파싱(parsing) 대신 AI를 선택하시나요?

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0