AI

Bright Data SDK로 브랜드 평판 모니터링 도구 구축하기

Bright Data SDK, OpenAI, SendGrid를 활용하여 브랜드 평판 모니터링을 위한 AI 기반 워크플로우 구축 방법을 알아보세요.
1 분 읽기
How to Build an AI Workflow for Brand Reputation Monitoring with Bright Data's SDK

이 튜토리얼에서는 다음을 배울 수 있습니다:

  1. 왜 맞춤형 브랜드 모니터링 솔루션이 필요한지.
  2. Bright Data SDK, OpenAI, SendGrid를 활용해 구축하는 방법.
  3. Python으로 브랜드 평판 모니터링 AI 워크플로를 구현하는 방법.

모든 프로젝트 파일은 GitHub 저장소에서 확인할 수 있습니다. 이제 시작해 보겠습니다!

왜 맞춤형 브랜드 모니터링 솔루션을 구축해야 할까요?

브랜드 모니터링은 마케팅에서 가장 중요한 작업 중 하나이며, 이를 지원하기 위한 여러 온라인 서비스가 존재합니다. 이러한 솔루션의 문제점은 비용이 비싸고 특정 요구사항에 맞지 않을 수 있다는 점입니다.

이 때문에 맞춤형 브랜드 평판 모니터링 솔루션을 구축하는 것이 합리적입니다. 처음에는 복잡한 목표처럼 느껴져 부담스러울 수 있습니다. 그러나 적절한 도구(곧 보게 될 것처럼)를 사용하면 완전히 달성 가능합니다.

브랜드 평판 AI 워크플로 설명

가장 먼저, 브랜드에 대한 신뢰할 수 있는 외부 정보 없이는 효과적인 브랜드 모니터링 도구를 구축할 수 없습니다. 이를 위한 훌륭한 정보원은 구글 뉴스입니다. 일간 뉴스 기사에서 브랜드에 대해 어떤 내용이 언급되고 있는지, 그리고 그 뒤에 숨은 감정을 이해함으로써 정보에 기반한 의사 결정을 내릴 수 있습니다. 궁극적인 목표는 브랜드에 대응하고, 보호하며, 홍보하는 것입니다.

문제는 뉴스 기사를 스크래핑하는 것이 어렵다는 점입니다. 특히 Google 뉴스는 여러 가지 봇 방지 조치로 보호되고 있습니다. 게다가 각 뉴스 출처마다 고유한 보호 장치가 적용된 자체 웹사이트를 운영하고 있어, 프로그래밍 방식으로 뉴스 데이터를 일관되게 수집하기가 어렵습니다.

이때 Bright Data가 해결책이 됩니다. 웹 검색 및 스크래핑 기능을 바탕으로, Bright Data는 다양한 제품과 통합 솔루션을 제공하여 어떤 웹사이트에서든 AI 활용이 가능한 공개 웹 데이터에 프로그래밍 방식으로 접근할 수 있게 합니다.

특히 새로운 Bright Data SDK를 사용하면 몇 줄의 Python 코드만으로 가장 유용한 Bright Data 솔루션을 간편하게 활용할 수 있습니다!

뉴스 데이터를 확보한 후에는 AI를 활용해 가장 관련성 높은 기사를 선별하고 감정 분석 및 브랜드 인사이트를 도출할 수 있습니다. 이후 Twilio SendGrid 같은 서비스를 통해 생성된 보고서를 마케팅 팀 전체에 전송할 수 있습니다. 고수준에서 이는 맞춤형 브랜드 평판 AI 워크플로우가 수행하는 작업과 정확히 일치합니다.

이제 기술적 관점에서 이를 구현하는 방법을 자세히 살펴보겠습니다!

기술적 단계

브랜드 평판 모니터링 AI 워크플로우 구현 단계는 다음과 같습니다:

  1. 환경 변수 로드: Bright Data, OpenAI, SendGrid API 키를 환경 변수에서 로드합니다. 이 키들은 워크플로를 구동하는 타사 서비스에 연결하는 데 필요합니다.
  2. 구성 파일 로드: 초기 검색 쿼리, 보고서에 포함할 뉴스 기사 수, 발신자 이메일 주소 및 수신자 이메일 주소가 포함된 JSON 구성 파일(예: config.json)을 읽습니다.
  3. Google 뉴스 페이지 URL 가져오기: Bright Data SDK를 사용하여 구성된 검색어에 대한 검색 엔진 결과 페이지(SERP)를 스크래핑합니다. 각 SERP에서 Google 뉴스 페이지 URL에 접근합니다.
  4. Google 뉴스 페이지 스크래핑: Bright Data SDK를 활용하여 전체 Google 뉴스 페이지를 마크다운(Markdown) 형식으로 스크래핑합니다. 각 페이지에는 여러 뉴스 기사 URL이 포함됩니다.
  5. AI로 주요 뉴스 식별: 스크랩한 Google 뉴스 페이지를 OpenAI 모델에 입력하여 브랜드 모니터링에 가장 적합한 뉴스 기사를 선별합니다.
  6. 개별 뉴스 기사 스크래핑: Bright Data SDK를 사용하여 AI가 반환한 각 뉴스 기사의 콘텐츠를 가져옵니다.
  7. 브랜드 평판 분석을 위한 기사 분석: 각 뉴스 기사를 AI에 입력하여 요약, 감정 분석 지표, 브랜드 평판에 대한 핵심 인사이트를 제공하도록 요청합니다.
  8. 최종 HTML 보고서 생성: 뉴스 분석 결과를 AI에 전달하여 체계적인 HTML 보고서를 생성하도록 요청합니다.
  9. 이메일로 보고서 발송: SendGrid SDK를 활용하여 AI가 생성한 HTML 보고서를 지정된 수신자에게 발송하여 브랜드 평판에 대한 포괄적인 개요를 제공합니다.
AI workflow flowchart

이 AI 워크플로를 Python으로 구현하는 방법을 확인하세요!

Bright Data SDK를 활용한 AI 기반 브랜드 평판 워크플로 구축

이 튜토리얼 섹션에서는 브랜드 평판을 모니터링하는 AI 워크플로우 구축 방법을 배웁니다. 필요한 브랜드 뉴스 데이터는 Bright Data Python SDK를 통해 Bright Data에서 조달됩니다. AI 기능은 OpenAI에서 제공하며, 이메일 발송은 SendGrid를 통해 처리됩니다.

이 튜토리얼을 마치면 결과를 직접 수신함으로 전달하는 완전한 Python AI 워크플로우를 갖게 됩니다. 출력 보고서는 브랜드가 인지해야 할 주요 뉴스를 식별하여 신속한 대응과 강력한 브랜드 입지 유지를 위한 모든 정보를 제공합니다.

브랜드 평판 AI 워크플로를 구축해 보세요!

필수 준비 사항

이 튜토리얼을 따라하려면 다음이 준비되어 있어야 합니다:

Bright Data API 토큰이 아직 없다면 Bright Data에 가입하고 설정 가이드를 따르세요. 마찬가지로 OpenAI 공식 지침을 따라 OpenAI API 키를 획득하세요.

SendGrid의 경우 계정을 생성하고, 인증을 완료한 후 이메일 주소를 연결하고 도메인을 확인하세요. API 키를 생성하고 이를 통해 프로그래밍 방식으로 이메일을 발송할 수 있는지 확인하세요.

1단계: Python 프로젝트 생성

터미널을 열고 브랜드 평판 모니터링 AI 워크플로를 위한 새 디렉터리를 생성하세요:

mkdir brand-reputation-monitoring-workflow

brand-reputation-monitoring-workflow/ 폴더에는 AI 워크플로우용 Python 코드가 포함됩니다.

다음으로 프로젝트 디렉터리로 이동하여 가상 환경을 설정합니다:

cd brand-reputation-monitoring-workflow
python -m venv .venv

이제 선호하는 Python IDE에서 프로젝트를 로드하세요. Python 확장 프로그램이 설치된 Visual Studio Code 또는 PyCharm Community Edition을 권장합니다.

프로젝트 폴더 내에 workflow.py라는 새 파일을 추가하세요. 이제 프로젝트 구조는 다음과 같아야 합니다:

brand-reputation-monitoring-workflow/
├── .venv/
└── workflow.py

workflow.py는 메인 Python 파일이 될 것입니다.

가상 환경을 활성화하세요. Linux 또는 macOS에서는 다음 명령어를 실행하세요:

source .venv/bin/activate

Windows에서는 다음과 같이 실행하세요:

.venv/Scripts/activate

환경이 활성화된 상태에서 필요한 종속성을 설치합니다:

pip install python-dotenv brightdata-sdk openai sendgrid pydantic

방금 설치한 라이브러리는 다음과 같습니다:

  • python-dotenv: .env 파일에서 환경 변수를 불러와 API 키를 안전하게 관리하기 쉽게 합니다.
  • brightdata-sdk: Python에서 Bright Data의 스크래핑 도구 및 솔루션에 접근할 수 있도록 지원합니다.
  • openai: OpenAI의 언어 모델과 상호작용합니다.
  • sendgrid: Twilio SendGrid Web API v3를 사용하여 이메일을 빠르게 발송합니다.
  • pydantic: AI 출력 및 구성 설정을 위한 모델을 정의합니다.

완료! OpenAI, Bright Data SDK 및 SendGrid를 사용하여 브랜드 평판 모니터링 AI 워크플로를 구축할 준비가 된 Python 개발 환경입니다.

2단계: 환경 변수 읽기 설정

스크립트가 환경 변수에서 비밀 정보를 읽도록 구성합니다. workflow.py 파일에서 python-dotenv를 임포트하고 load_dotenv() 를 호출하여 환경 변수를 자동으로 로드합니다:

from dotenv import load_dotenv

load_dotenv()

이제 스크립트가 로컬 .env 파일에서 변수를 읽을 수 있습니다. 따라서 프로젝트 디렉토리 루트에 .env 파일을 생성하세요:

brand-reputation-monitoring-workflow/
├── .venv/
├── .env         # <-----------
└── workflow.py

.env 파일을 열고 OPENAI_API_KEY, BRIGHT_DATA_API_TOKEN, SENDGRID_API_KEY 환경 변수를 추가하세요:

OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
BRIGHT_DATA_API_TOKEN="<YOUR_BRIGHT_DATA_API_TOKEN>"
SENDGRID_API_KEY="<YOUR_SENDGRID_API_TOKEN>"

실제 자격 증명으로 자리 표시자를 대체하세요:

잘하셨습니다! 이제 환경 변수를 사용하여 타사 비밀 정보를 안전하게 구성했습니다.

3단계: SDK 초기화

필요한 임포트 추가부터 시작하세요:

from brightdata import bdclient
from openai import OpenAI
from sendgrid import SendGridAPIClient

그런 다음 SDK 클라이언트를 초기화하세요:

brightdata_client = bdclient()
openai_client = OpenAI()
sendgrid_client = SendGridAPIClient()

위의 세 줄은 다음을 초기화합니다:

  • Bright Data Python SDK
  • OpenAI Python SDK
  • SendGrid Python SDK

코드를 작성할 때 API 키 환경 변수를 수동으로 불러와 생성자에 전달할 필요가 없습니다. OpenAI SDK, Bright Data SDK, SendGrid SDK는 각각 OPENAI_API_KEY, BRIGHT_DATA_API_TOKEN, SENDGRID_API_KEY 환경 변수를 자동으로 탐색하기 때문입니다. 즉, .env에 해당 환경 변수가 설정되면 SDK가 자동으로 로드합니다.

특히, SDK는 구성된 API 키를 사용하여 사용자의 계정으로 해당 서버에 대한 기본 API 호출을 인증합니다.

중요: Bright Data SDK의 작동 방식과 Bright Data 계정의 필수 영역에 연결하는 방법에 대한 자세한 내용은 공식 GitHub 페이지 또는 문서를 참조하십시오.

완벽합니다! 브랜드 평판 모니터링 AI 워크플로우를 구축하기 위한 구성 요소가 이제 준비되었습니다.

4단계: Google 뉴스 URL 가져오기

워크플로 로직의 첫 번째 단계는 모니터링하려는 브랜드 관련 검색어에 대한 SERP를 스크래핑하는 것입니다. Bright Data SDK의 search() 메서드를 통해 이를 수행하면, 백그라운드에서 SERP API를 호출합니다.

그런 다음 search() 에서 받은 JSON 텍스트 응답을 파싱하여 Google 뉴스 페이지 URL에 접근합니다. URL은 다음과 같은 형식입니다:

https://www.google.com/search?sca_esv=7fb9df9863b39f3b&hl=en&q=nike&tbm=nws&source=lnms&fbs=AIIjpHxU7SXXniUZfeShr2fp4giZjSkgYzz5-5RrRWAIniWd7tzPwkE1KJWcRvaH01D-XIVr2cowAnfeRRP_dme4bG4a8V_AkFVl-SqROia4syDA2-hwysjgAT-v0BCNgzLBnrhEWcFR7F5dffabwXi9c9pDyztBxQc1yfKVagSlUz7tFb_e8cyIqHDK7O6ZomxoJkHRwfaIn-HHOcZcyM2n-MrnKKBHZg&sa=X&ved=2ahUKEwiX1vu4_KePAxVWm2oFHT6tKsAQ0pQJegQIPhAB

이 함수로 모든 것을 달성하세요:

def get_google_news_page_urls(search_queries):
    # 지정된 검색어에 대한 SERP(검색 결과 페이지)를 가져옵니다
    serp_results = brightdata_client.search(
        search_queries,
        search_engine="google",
        parse=True # SERP 결과를 파싱된 JSON 문자열로 가져오기 위해
    )

    news_page_urls = []
    for serp_result in serp_results:
        # JSON 문자열을 사전(dictionary)으로 로드
        serp_data = json.loads(serp_result)
        # 각 파싱된 SERP에서 Google 뉴스 URL 추출
        if serp_data.get("navigation"):
            for item in serp_data["navigation"]:
                if item["title"] == "News":
                    news_url = item["href"]
                    news_page_urls.append(news_url)

    return news_page_urls

search() 에 쿼리 배열을 전달하면(이 경우처럼), 해당 메서드는 각 쿼리에 대해 하나씩 총 여러 개의 SERP 배열을 반환합니다. parse가 True로 설정되어 있으므로, 각 결과는 JSON 문자열로 반환되며, 이를 Python 내장 json 모듈로 파싱해야 합니다.

Python 표준 라이브러리에서 json을 임포트하는 것을 잊지 마세요:

import json

훌륭합니다! 이제 브랜드와 관련된 Google 뉴스 페이지 URL 목록을 프로그래밍 방식으로 가져올 수 있습니다.

5단계: Google 뉴스 페이지를 스크래핑하고 최고의 뉴스 URL을 확보하기

단일 Google 뉴스 페이지에는 여러 뉴스 기사가 포함된다는 점을 명심하세요:

An example of a Google News page

따라서 핵심은 다음과 같습니다:

  1. Google 뉴스 페이지의 콘텐츠를 스크래핑하여 마크다운 형식으로 결과를 얻습니다.
  2. 이 마크다운 콘텐츠를 AI(이 경우 OpenAI 모델)에 입력하여 브랜드 평판 모니터링을 위한 상위 5개 뉴스 기사를 선별하도록 요청합니다.

이 함수로 첫 번째 미세 단계를 달성합니다:

def scrape_news_pages(news_page_urls):
    # 각 뉴스 페이지를 병렬로 스크래핑하고 마크다운 형식의 콘텐츠를 반환
    return brightdata_client.scrape(
        url=news_page_urls,
        data_format="markdown"
    ) 

내부적으로 Bright Data SDK의 scrape() 메서드는 Web Unlocker API를 호출합니다. URL 배열을 전달하면 scrape()는 모든 페이지를 동시에 가져오며 스크래핑 작업을 병렬로 수행합니다. 이 경우 API는 데이터를 마크다운 형식으로 반환하도록 구성되어 있으며, 이는 LLM 데이터 입력에 이상적입니다( Kaggle의 데이터 형식 벤치마크에서 입증됨).

그런 다음 두 번째 마이크로 단계를 다음과 같이 완료하세요:

def get_best_news_urls(news_pages, num_news):
    # GPT를 사용하여 가장 관련성 높은 뉴스 URL 추출
    response = openai_client.responses.parse(
        model="gpt-5-mini",
        input=[
            {
                "role": "system",
                "content": f"텍스트에서 브랜드 평판 모니터링을 위한 가장 관련성 높은 뉴스 {num_news}개를 추출하고 URL 문자열 목록으로 반환하세요."
            },
            {
                "role": "user",
                "content": "nn---------------nn".join(news_pages)
            },
        ],
        text_format=URLList,
    )

    return response.output_parsed.urls

이 코드는 단순히 이전 함수에서 생성된 마크다운 텍스트 출력을 연결하여 GPT-5-mini OpenAI 모델에 전달하고, 가장 관련성 높은 URL을 추출하도록 요청합니다.

출력은 URLList 모델을 따를 것으로 예상되며, 이는 다음과 같이 정의된 Pydantic 모델입니다:

class URLList(BaseModel):
    urls: List[str]

parse() 메서드의text_format 옵션을 통해 OpenAI API에 결과를 URLList 인스턴스로 반환하도록 지시합니다. 기본적으로 각 문자열이 URL을 나타내는 문자열 목록을 얻게 됩니다.

pydantic에서 필요한 클래스를 임포트합니다:

from pydantic import BaseModel
from typing import List

훌륭합니다! 이제 구조화된 뉴스 URL 목록을 확보하여 브랜드 평판 모니터링을 위한 스크래핑 및 분석을 진행할 준비가 되었습니다.

6단계: 뉴스 페이지 스크래핑 및 브랜드 평판 모니터링 분석

이제 최고의 뉴스 URL 목록을 확보했으니, 다시 scrape()를 사용해 해당 콘텐츠를 마크다운 형식으로 가져옵니다:

def scrape_news_articles(news_urls):
    # 각 뉴스 URL을 스크래핑하여 URL과 콘텐츠가 포함된 딕셔너리 목록 반환
    news_content_list = brightdata_client.scrape(
        url=news_urls,
        data_format="markdown"
    )

    news_list = []
    for url, content in zip(news_urls, news_content_list):
        news_list.append({
            "url": url,
            "content": content
        })

    return news_list

해당 뉴스 기사가 호스팅된 도메인이나 적용된 스크래핑 방지 조치와 상관없이, Web Unlocker API가 이를 처리하여 각 기사의 내용을 마크다운 형식으로 반환합니다. 구체적으로, 뉴스 기사는 병렬로 스크래핑됩니다. 어떤 뉴스 URL이 어떤 마크다운 출력에 해당하는지 추적하려면 zip()을 사용하세요.

다음으로 각 마크다운 뉴스 콘텐츠를 OpenAI에 입력하여 브랜드 평판 분석을 수행합니다. 각 기사에서 다음을 추출합니다:

  1. 제목
  2. URL
  3. 간단한 요약
  4. 간단한 감정 레이블(예: “긍정적”, “부정적”, “중립적”)
  5. 실행 가능한, 짧고 이해하기 쉬운 인사이트 3~5개

다음 함수로 이를 달성하세요:

def process_news_list(news_list):
    # 분석된 뉴스 기사 저장 위치
    news_analysis_list = []

    # 브랜드 평판 모니터링 인사이트를 위해 GPT로 각 뉴스 기사 분석
    for news in news_list:
        response = openai_client.responses.parse(
            model="gpt-5-mini",
            input=[
                {
                    "role": "system",
                    "content": f"""
                        뉴스 콘텐츠를 주어졌을 때:
                        1. 제목을 추출하세요.
                        2. URL을 추출하세요.
                        3. 30단어 이내로 요약문을 작성하세요.
                        4. 뉴스의 감정을 "긍정적", "부정적", "중립적" 중 하나로 추출하세요.
                        5. 뉴스에서 브랜드 평판에 관한 실행 가능한 핵심 인사이트 3~5개(10~12단어 이내)를 명확하고 간결하며 직설적인 언어로 추출하세요.
                    """
                },
                {
                    "role": "user",
                    "content": f"NEWS URL: {news["url"]}nnNEWS CONTENT:{news["content"]}"
                },
            ],
            text_format=NewsAnalysis,
        )

        # 분석된 뉴스 객체를 출력으로 가져와 목록에 추가
        news_analysis = response.output_parsed
        news_analysis_list.append(news_analysis)

    return news_analysis_list

이번에는 text_format 에 설정된 Pydantic 모델은 다음과 같습니다:

class NewsAnalysis(BaseModel):
    title: str
    url: str
    summary: str
    sentiment_analysis: str
    insights: List[str]

따라서 process_news_list() 함수의 결과는 NewsAnalysis 객체들의 리스트가 됩니다.

멋지네요! 브랜드 평판 모니터링을 위한 AI 기반 뉴스 처리 시스템이 완성되었습니다.

7단계: 이메일 보고서 생성 및 발송

이메일이 어떻게 구성되어 고객의 수신함에 깔끔하게 표시되는지 궁금해 본 적 있나요? 대부분의 이메일 본문은 사실 구조화된 HTML 페이지이기 때문입니다. 결국 이메일 프로토콜은 HTML 문서 전송을 지원합니다.

앞서 생성한 뉴스 분석 객체 목록을 JSON으로 변환한 후 AI에 전달하여 이메일 발송 준비가 된 HTML 문서를 생성하도록 요청합니다:

def create_html_email_body(news_analysis_list):
    # 분석된 뉴스로부터 구조화된 HTML 이메일 본문 생성
    response = openai_client.responses.create(
        model="gpt-5-mini",
        input=f"""
        아래 내용을 바탕으로, 잘 포맷되고 반응형이며 발송 준비가 된 구조화된 HTML 이메일 본문을 생성하세요.
        적절한 위치에 제목, 단락, 색상 라벨, 링크를 올바르게 사용하십시오.
        헤더나 푸터 섹션을 포함하지 말고, 오직 이 정보만 포함하십시오—다른 내용은 포함하지 마십시오.

        콘텐츠:
        {[json.dumps([item.model_dump() for item in news_analysis_list], indent=2)]}
        """
    )
    return response.output_text

마지막으로 Twilio SendGrid SDK를 사용하여 프로그래밍 방식으로 이메일을 발송합니다:

def send_email(sender, recipients, html_body):
    # SendGrid를 사용하여 HTML 이메일 전송
    message = Mail(
        from_email=sender,
        to_emails=recipients,
        subject="브랜드 모니터링 주간 보고서",
        html_content=html_body
    )
    sendgrid_client.send(message)

이를 위해서는 다음 임포트가 필요합니다:

from sendgrid.helpers.mail import Mail

자, 이제 시작합니다! 브랜드 평판 모니터링 AI 워크플로우 구현을 위한 모든 함수가 이제 구현되었습니다.

단계 #8: 환경 설정 및 구성값 불러오기

이전 단계에서 정의된 일부 함수는 특정 인자(예: search_queries, num_news, sender, recipients)를 받습니다. 이러한 값은 실행마다 달라질 수 있으므로 Python 스크립트에 하드코딩해서는 안 됩니다.

대신, 다음 필드를 포함하는 config.json 파일에서 읽어와야 합니다:

  • search_queries: 뉴스를 검색할 브랜드 평판 쿼리 목록.
  • num_news: 최종 보고서에 포함할 뉴스 기사 수.
  • sender: 보고서가 발송될 SendGrid 승인 이메일 주소.
  • recipients: HTML 보고서를 발송할 이메일 주소 목록입니다.

다음 Pydantic 클래스를 사용하여 구성 객체를 모델링하세요:

class Config(BaseModel):
    search_queries: List[str] = Field(..., min_items=1)
    num_news: int = Field(..., gt=0)
    sender: str = Field(..., min_length=1)
    recipients: List[str] = Field(..., min_items=1)

Field 정의는 구성이 예상 형식을 준수하도록 검증 규칙을 지정합니다. 다음으로 임포트하세요:

from pydantic import Field

다음으로 로컬 config.json 파일에서 워크플로 구성을 읽고 Config 객체로 파싱합니다:

with open("config.json", "r", encoding="utf-8") as f:
    raw_config = json.load(f)
    config = Config.model_validate(raw_config) 

프로젝트 디렉터리에 config.json 파일을 추가하세요:

brand-reputation-monitoring-workflow/
├── .venv/
├── .env         
├── config.json         # <-----------
└── workflow.py

다음과 같은 내용으로 채우세요:

{
  "search_queries": ["apple", "iphone", "ipad"],
  "sender": "[email protected]",
  "recipients": ["[email protected]", "[email protected]", "[email protected]"],
  "num_news": 5
}

값은 특정 목표에 맞게 조정하세요. 또한 sender 필드는 SendGrid 계정에서 인증된 이메일 주소여야 합니다. 그렇지 않으면 send_email() 함수가 403 Forbidden 오류로 실패합니다.

잘하셨습니다! 한 단계만 더 진행하면 워크플로가 완성됩니다.

9단계: 메인 함수 정의

이제 모든 것을 조합할 시간입니다. 사전 정의된 각 함수를 올바른 순서로 호출하고, 구성 파일에서 적절한 입력값을 전달하세요:

search_queries = config.search_queries
print(f"다음 검색어에 대한 Google 뉴스 페이지 URL을 가져옵니다: {", ".join(search_queries)}")
google_news_page_urls = get_google_news_page_urls(search_queries)
print(f"{len(google_news_page_urls)} 개의 Google 뉴스 페이지 URL을 가져왔습니다!n")

print("각 Google 뉴스 페이지에서 콘텐츠를 스크래핑 중...")
scraped_news_pages = scrape_news_pages(google_news_page_urls)
print("Google 뉴스 페이지 스크래핑 완료!n")

print("가장 관련성 높은 뉴스 URL 추출 중...")
news_urls = get_best_news_urls(scraped_news_pages, config.num_news)
print(f"{len(news_urls)}개의 뉴스 기사 발견:n" + "n".join(f"- {news}" for news in news_urls) + "n")

print("선택된 뉴스 기사 스크래핑 중...")
news_list = scrape_news_articles(news_urls)
print(f"{len(news_urls)} 개의 뉴스 기사 스크래핑 완료!")

print("브랜드 평판 모니터링을 위한 각 뉴스 분석 중...")
news_analysis_list = process_news_list(news_list)
print("뉴스 분석 완료!n")

print("HTML 이메일 본문 생성 중...")
html = create_html_email_body(news_analysis_list)
print("HTML 이메일 본문 생성 완료!n")

print("브랜드 평판 모니터링 HTML 보고서가 포함된 이메일 발송 중...")
send_email(config.sender, config.recipients, html)
print("이메일 발송 완료!")

참고: 워크플로 완료까지 시간이 다소 소요될 수 있으므로, 터미널에서 진행 상황을 추적할 수 있도록 로그를 추가하는 것이 좋습니다. 미션 완료!

10단계: 모든 것을 통합하기

워크플로우 파일 (workflow.py )의 최종 코드는 다음과 같습니다:

from dotenv import load_dotenv
from brightdata import bdclient
from openai import OpenAI
from sendgrid import SendGridAPIClient
from pydantic import BaseModel, Field
from typing import List
import json
from sendgrid.helpers.mail import Mail

# .env 파일에서 환경 변수 로드
load_dotenv()

# Bright Data SDK 클라이언트 초기화
brightdata_client = bdclient()
# OpenAI SDK 클라이언트 초기화
openai_client = OpenAI()
# SendGrid SDK 클라이언트 초기화
sendgrid_client = SendGridAPIClient()

# Pydantic 모델
class Config(BaseModel):
    search_queries: List[str] = Field(..., min_items=1)
    num_news: int = Field(..., gt=0)
    sender: str = Field(..., min_length=1)
    recipients: List[str] = Field(..., min_items=1)

class URLList(BaseModel):
    urls: List[str]

class NewsAnalysis(BaseModel):
    title: str
    url: str
    summary: str
    sentiment_analysis: str
    insights: List[str]

def get_google_news_page_urls(search_queries):
    # 지정된 검색어에 대한 SERP(검색 결과 페이지) 가져오기
    serp_results = brightdata_client.search(
        search_queries,
        search_engine="google",
        parse=True # SERP 결과를 파싱된 JSON 문자열로 가져오기
    )

    news_page_urls = []
    for serp_result in serp_results:
        # JSON 문자열을 사전으로 로드
        serp_data = json.loads(serp_result)
        # 파싱된 각 SERP에서 Google 뉴스 URL 추출
        if serp_data.get("navigation"):
            for item in serp_data["navigation"]:
                if item["title"] == "News":
                    news_url = item["href"]
                    news_page_urls.append(news_url)

    return news_page_urls

def scrape_news_pages(news_page_urls):
    # 각 뉴스 페이지를 병렬로 스크래핑하고 마크다운 형식으로 콘텐츠 반환
    return brightdata_client.scrape(
        url=news_page_urls,
        data_format="markdown"
    )

def get_best_news_urls(news_pages, num_news):
    # GPT를 사용하여 가장 관련성 높은 뉴스 URL 추출
    response = openai_client.responses.parse(
        model="gpt-5-mini",
        input=[
            {
                "role": "system",
                "content": f"텍스트에서 브랜드 평판 모니터링을 위한 가장 관련성 높은 뉴스 {num_news}개를 추출하여 URL 문자열 목록으로 반환해 주세요."
            },
            {
                "role": "user",
                "content": "nn---------------nn".join(news_pages)
            },
        ],
        text_format=URLList,
    )

    return response.output_parsed.urls

def scrape_news_articles(news_urls):
    # 각 뉴스 URL을 스크래핑하여 URL과 콘텐츠가 포함된 딕셔너리 목록 반환
    news_content_list = brightdata_client.scrape(
        url=news_urls,
        data_format="markdown"
    )

    news_list = []
    for url, content in zip(news_urls, news_content_list):
        news_list.append({
            "url": url,
            "content": content
        })

    return news_list

def process_news_list(news_list):
    # 분석된 뉴스 기사를 저장할 위치
    news_analysis_list = []

    # 브랜드 평판 모니터링 인사이트를 위해 GPT로 각 뉴스 기사 분석
    for news in news_list:
        response = openai_client.responses.parse(
            model="gpt-5-mini",
            input=[
                {
                    "role": "system",
                    "content": f"""
                        뉴스 콘텐츠를 바탕으로:
                        1. 제목을 추출하세요.
                        2. URL을 추출하세요.
                        3. 30단어 이내로 요약문을 작성하세요.
                        4. 뉴스의 감정을 다음 중 하나로 추출하세요: "긍정적", "부정적", 또는 "중립적".
                        5. 뉴스에서 브랜드 평판에 관한 실행 가능한 짧은 인사이트(10~12단어 이내) 상위 3~5개를 추출하여 명확하고 간결하며 직설적인 언어로 제시하세요.
                    """
                },
                {
                    "role": "user",
                    "content": f"NEWS URL: {news["url"]}nnNEWS CONTENT:{news["content"]}"
                },
            ],
            text_format=NewsAnalysis,
        )

        # 분석된 뉴스 객체를 출력으로 받아 목록에 추가
        news_analysis = response.output_parsed
        news_analysis_list.append(news_analysis)

    return news_analysis_list

def create_html_email_body(news_analysis_list):
    # 분석된 뉴스로 구조화된 HTML 이메일 본문 생성
    response = openai_client.responses.create(
        model="gpt-5-mini",
        input=f"""
        아래 내용을 바탕으로, 잘 포맷되고 반응형이며 발송 준비가 된 구조화된 HTML 이메일 본문을 생성하세요.
        적절한 위치에 제목, 단락, 색상 라벨, 링크를 올바르게 사용하세요.
        헤더나 푸터 섹션은 포함하지 말고, 오직 이 정보만 포함하세요—다른 내용은 포함하지 마세요.

        콘텐츠:
        {[json.dumps([item.model_dump() for item in news_analysis_list], indent=2)]}
        """
    )
    return response.output_text

def send_email(sender, recipients, html_body):
    # SendGrid를 사용하여 HTML 이메일 전송
    message = Mail(
        from_email=sender,
        to_emails=recipients,
        subject="브랜드 모니터링 주간 보고서",
        html_content=html_body
    )
    sendgrid_client.send(message)

def main():
    # 설정 파일 읽기 및 유효성 검사
    with open("config.json", "r", encoding="utf-8") as f:
        raw_config = json.load(f)
        config = Config.model_validate(raw_config)

    search_queries = config.search_queries
    print(f"다음 검색어에 대한 Google 뉴스 페이지 URL을 가져옵니다: {", ".join(search_queries)}")
    google_news_page_urls = get_google_news_page_urls(search_queries)
    print(f"{len(google_news_page_urls)} 개의 Google 뉴스 페이지 URL을 가져왔습니다!n")

    print("각 Google 뉴스 페이지에서 콘텐츠 스크래핑 중...")
    scraped_news_pages = scrape_news_pages(google_news_page_urls)
    print("Google 뉴스 페이지 스크래핑 완료!n")

    print("가장 관련성 높은 뉴스 URL 추출 중...")
    news_urls = get_best_news_urls(scraped_news_pages, config.num_news)
    print(f"{len(news_urls)} 개의 뉴스 기사 발견:n" + "n".join(f"- {news}" for news in news_urls) + "n")

    print("선택된 뉴스 기사 스크래핑 중...")
    news_list = scrape_news_articles(news_urls)
    print(f"{len(news_urls)}개 뉴스 기사 스크래핑 완료!")

    print("브랜드 평판 모니터링을 위해 각 뉴스 분석 중...")
    news_analysis_list = process_news_list(news_list)
    print("뉴스 분석 완료!n")

    print("HTML 이메일 본문 생성 중...")
    html = create_html_email_body(news_analysis_list)
    print("HTML 이메일 본문 생성 완료!n")

    print("브랜드 평판 모니터링 HTML 보고서가 포함된 이메일 발송 중...")
    send_email(config.sender, config.recipients, html)
    print("이메일 발송 완료!")

# 메인 함수 실행
if __name__ == "__main__":
    main()

자, 이제 완성되었습니다! Bright Data SDK, OpenAI API, Twilio SendGrid SDK 덕분에 200줄 미만의 코드로 AI 기반 브랜드 평판 모니터링 워크플로를 구축할 수 있었습니다.

11단계: 워크플로 테스트

검색어(search_queries)"나이키(nike)""나이키 신발(nike shoes)"라고 가정합니다. 뉴스 수(num_news) 는 5로 설정되었으며, 보고서는 개인 이메일로 발송되도록 구성되었습니다( 발신자와 수신자 첫 번째 항목에 동일한 이메일 주소를 사용할 수 있음 ).

활성화된 가상 환경에서 다음 명령어로 워크플로를 실행하세요:

python workflow.py

터미널에 다음과 같은 결과가 표시됩니다:

다음 검색어에 대한 Google 뉴스 페이지 URL을 검색 중: nike, nike shoes
Google 뉴스 페이지 URL 2개 검색 완료!

각 Google 뉴스 페이지에서 콘텐츠 스크래핑 중...
Google 뉴스 페이지 스크래핑 완료!

가장 관련성 높은 뉴스 URL 추출 중...
발견된 뉴스 기사 5개:
- https://www.espn.com/wnba/story/_/id/46075454/caitlin-clark-becomes-nike-newest-signature-athlete
- https://wwd.com/footwear-news/sneaker-news/nike-acg-radical-airflow-ultrafly-release-dates-1238068936/
- https://www.runnersworld.com/news/a65881486/cooper-lutkenhaus-professional-contract-nike/
- https://hypebeast.com/2025/8/nike-kobe-3-protro-low-reveal-info
- https://wwd.com/footwear-news/sneaker-news/nike-air-diamond-turf-must-be-the-money-release-date-1238075256/

선택한 뉴스 기사 스크래핑 중...
5개 뉴스 기사 스크래핑 완료!

브랜드 평판 모니터링을 위한 각 뉴스 기사 분석 중...
뉴스 분석 완료!

HTML 이메일 본문 생성 중...
HTML 이메일 본문 생성 완료!

브랜드 평판 모니터링 HTML 보고서가 포함된 이메일 발송 중...
이메일 발송 완료!

참고: 결과는 이용 가능한 뉴스에 따라 달라집니다. 따라서 이 튜토리얼을 읽을 때쯤이면 위 결과와 동일하지 않을 것입니다.

“이메일 발송 완료!” 메시지 이후, 수신함에서 “브랜드 모니터링 주간 보고서” 이메일을 확인하실 수 있습니다:

A “Brand Monitoring Weekly Report” email in your inbox

이메일을 열면 다음과 같은 내용이 포함되어 있습니다:

The “Brand Monitoring Weekly Report” HTML report

보시다시피, AI는 요청된 모든 데이터를 포함해 시각적으로 매력적인 브랜드 모니터링 보고서를 생성했습니다.

보고서를 스크롤하면 다음과 같은 내용을 확인할 수 있습니다:

Scrolling through the produced HTML report

감정 라벨은 감정을 빠르게 파악할 수 있도록 색상으로 구분되어 있습니다. 또한 뉴스 항목의 제목은 원본 기사로 연결되는 링크이므로 파란색으로 표시됩니다.

자, 이제 시작해 보세요! 몇 가지 검색어로 시작하여 구조화된 브랜드 모니터링 보고서가 포함된 이메일을 받게 되었습니다.

이 모든 것은 Bright Data SDK에서 제공하는 웹 데이터 스크래핑 솔루션의 힘 덕분입니다. 스크래핑된 페이지는 LLM 최적화 마크다운 형식으로 반환되므로 어떤 AI 모델이든 여러분의 요구에 맞게 분석할 수 있다는 점을 기억하세요. 지원되는 다른 에이전트 및 AI 워크플로 사용 사례를 살펴보세요 !

다음 단계

현재의 브랜드 평판 모니터링 AI 워크플로는 이미 상당히 정교하지만, 다음과 같은 아이디어로 더욱 개선할 수 있습니다:

  • 이전에 다룬 뉴스를 위한 메모리 레이어 추가: 동일한 기사를 여러 번 분석하는 것을 방지하여 중복을 줄이고 보고서 정확도를 높입니다.
  • 표준화를 위한 SendGrid 템플릿 도입: AI가 실행할 때마다 구조가 약간 다른 HTML 보고서를 생성할 수 있습니다. 레이아웃을 일관되게 유지하려면 SendGrid 템플릿을 정의하고, 생성된 뉴스 분석 데이터로 채운 후 SendGrid SDK를 통해 전송하세요. 자세한 내용은 공식 문서를 참조하세요.
  • 생성된 HTML 보고서를 클라우드에 저장: 보고서를 S3에 저장하여 보관하고, 향후 브랜드 모니터링 분석에 활용할 수 있도록 합니다.

결론

본 문서에서는 Bright Data의 웹 검색 및 스크래핑 기능을 활용하여 AI 기반 브랜드 평판 워크플로를 구축하는 방법을 살펴보았습니다. 간단한 메서드 호출로 Bright Data 제품에 접근할 수 있는 새로운 Bright Data SDK 덕분에 이 프로세스는 더욱 간편해졌습니다.

여기 소개된 AI 워크플로는 브랜드 모니터링과 실행 가능한 인사이트를 저렴한 비용으로 얻고자 하는 마케팅 팀에 이상적입니다. 브랜드 보호 및 의사 결정을 지원하는 상황별 지침을 제공하여 시간과 노력을 절약하는 데 도움이 됩니다.

보다 고급 워크플로우를 구축하려면 실시간 웹 데이터 수집, 검증 및 변환을 위한 Bright Data AI 인프라의 전체 솔루션 범위를 살펴보세요.

무료 Bright Data 계정을 생성하고 AI 활용이 가능한 웹 데이터 솔루션으로 실험을 시작해 보세요!