Google 트렌드는사람들이 온라인에서 무엇을 검색하는지에 대한 통찰력을 제공하는 무료 도구입니다. 이러한 검색 트렌드를 분석함으로써 기업은 신흥 시장 동향을 파악하고 소비자 행동을 이해하며, 데이터 기반 의사결정을 통해 판매 및 마케팅 노력을 강화할 수 있습니다. Google 트렌드에서 데이터를 추출하면 기업은 전략을 맞춤화하여 경쟁에서 앞서 나갈 수 있습니다.
이 글에서는 Python을 사용하여 Google 트렌드에서 데이터를 스크래핑하는 방법과 해당 데이터를 효과적으로 저장 및 분석하는 방법을 배울 수 있습니다.
구글 트렌드 데이터를 스크래핑해야 하는 이유
구글 트렌드 데이터 수집 및 분석은 다음과 같은 다양한 상황에서 유용합니다:
- 키워드 연구:콘텐츠 제작자와 SEO 전문가는 웹사이트로 더 많은 유기적 트래픽을 유도하기 위해 어떤 키워드가 주목받고 있는지 파악해야 합니다. Google 트렌드는 지역, 카테고리 또는 시간별로 유행하는 검색어를 탐색할 수 있게 하여 변화하는 사용자 관심사에 기반한 콘텐츠 전략 최적화를 가능하게 합니다.
- 시장 조사:마케터는 고객의 관심사를 이해하고 수요 변화를 예측하여 정보에 기반한 의사 결정을 내려야 합니다. Google 트렌드 데이터를 스크래핑하고 분석하면 고객의 검색 패턴을 파악하고 시간에 따른 트렌드를 모니터링할 수 있습니다.
- 사회 연구:지역 및 글로벌 이벤트, 기술 혁신, 경제 변화, 정치적 발전 등 여러 요인이 대중 관심사와 검색 트렌드에 상당한 영향을 미칠 수 있습니다. Google 트렌드 데이터는 시간에 따른 이러한 변화하는 트렌드에 대한 귀중한 통찰력을 제공하여 포괄적인 분석과 정보에 기반한 미래 예측을 가능하게 합니다.
- 브랜드 모니터링:기업과 마케팅 팀은 시장에서 자사 브랜드가 어떻게 인식되는지 모니터링해야 합니다. Google 트렌드 데이터를 스크래핑하면 자사 브랜드의 가시성을 경쟁사와 비교하고 대중 인식 변화에 신속히 대응할 수 있습니다.
구글 트렌드 스크래핑을 대체하는 Bright Data의 솔루션 – Bright Data의 SERP API
구글 트렌드를 수동으로 스크래핑하는 대신, Bright Data의 SERP API를 사용하여 검색 엔진에서 실시간 데이터 수집을 자동화하세요. SERP API는 정확한 지역 타겟팅과 차단 또는 CAPTCHA 위험 없이 검색 결과 및 트렌드와 같은 구조화된 데이터를 제공합니다. 성공적인 요청에 대해서만 비용을 지불하며, 데이터는 JSON 또는 HTML 형식으로 제공되어 손쉬운 통합이 가능합니다.
이 솔루션은 더 빠르고 확장성이 뛰어나며 복잡한 스크래핑 스크립트가 필요 없습니다. 무료 체험을 시작하고 Bright Data의 Google 트렌드 스크래퍼로 데이터 수집을 간소화하세요.
Google 트렌드에서 데이터 스크래핑하는 방법
Google 트렌드는 트렌드 데이터 스크래핑을 위한 공식 API를 제공하지 않지만,pytrends와 같은 여러 타사 API 및 라이브러리를 사용하여 이 정보에 접근할 수 있습니다.pytrends는 Google 트렌드에서 보고서를 자동으로 다운로드할 수 있는 사용자 친화적인 API를 제공하는 Python 라이브러리입니다. 그러나 pytrends는 사용하기 쉽지만 동적으로 렌더링되거나 상호작용 요소 뒤에 있는 데이터에 접근할 수 없어 제한된 데이터만 제공합니다. 이 문제를 해결하기 위해Selenium과Beautiful Soup을활용하여 Google 트렌드를 스크래핑하고 동적으로 렌더링된 웹 페이지에서 데이터를 추출할 수 있습니다. Selenium은 JavaScript를 사용하여 콘텐츠를 동적으로 로드하는 웹사이트와 상호작용하고 스크래핑하는 오픈 소스 도구입니다. Beautiful Soup은 스크래핑된 HTML 콘텐츠를 파싱하여 웹 페이지에서 특정 데이터를 추출할 수 있도록 지원합니다.
이 튜토리얼을 시작하기 전에, 컴퓨터에Python이설치 및 설정되어 있어야 합니다. 또한 다음 몇 섹션에서 구축할 Python 스크립트를 위한 빈 프로젝트 디렉터리를 생성해야 합니다.
가상 환경 생성
가상 환경은 Python 패키지를 별도의 디렉터리에 격리하여 버전 충돌을 방지합니다. 새 가상 환경을 생성하려면 터미널에서 다음 명령을 실행하세요:
# 명령 실행 전 프로젝트 디렉토리 루트로 이동
python -m venv myenv
이 명령어는 프로젝트 디렉터리에 myenv라는 폴더를 생성합니다. 다음 명령어를 실행하여 가상 환경을 활성화하세요:
source myenv/bin/activate
이후 실행되는 모든 Python 또는 pip 명령어도 이 환경에서 실행됩니다.
의존성 설치
앞서 논의한 바와 같이, 웹 페이지를 스크래핑하고 파싱하려면 Selenium과 Beautiful Soup이 필요합니다. 또한 스크래핑된 데이터를 분석하고 시각화하려면pandas와MatplotlibPython 모듈을 설치해야 합니다. 다음 명령어를 사용하여 이러한 패키지를 설치하세요:
pip install beautifulsoup4 pandas matplotlib selenium
Google 트렌드 검색 데이터 쿼리
Google 트렌드 대시보드를사용하면 지역, 기간, 카테고리별로 검색 트렌드를 탐색할 수 있습니다. 예를 들어, 다음 URL은 지난 7일 동안 미국에서 커피에 대한 검색 트렌드를 보여줍니다:
https://trends.google.com/trends/explore?date=now%207-d&geo=US&q=coffee
브라우저에서 이 웹 페이지를 열면 데이터가 JavaScript를 사용하여 동적으로 로드되는 것을 확인할 수 있습니다. 동적 콘텐츠를 스크래핑하려면 클릭, 입력, 스크롤과 같은 사용자 상호작용을 모방하는Selenium WebDriver를 사용할 수 있습니다.
Python 스크립트에서webdriver를사용해 브라우저 창에 웹 페이지를 로드하고 콘텐츠가 로드된 후 페이지 소스를 추출할 수 있습니다. 동적 콘텐츠를 처리하려면 페이지 소스를 가져오기 전에 모든 콘텐츠가 로드되도록time.sleep을명시적으로 추가하세요. 동적 콘텐츠 처리 기법에 대해 더 알고 싶다면이 가이드를 참고하세요.
프로젝트 루트에 main.py 파일을 생성하고 다음 코드 스니펫을 추가하세요:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
def get_driver():
# Chrome 바이너리 위치 경로 업데이트
CHROME_PATH = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
options = Options()
# options.add_argument("--headless=new")
options.binary_location = CHROME_PATH
driver = webdriver.Chrome(options=options)
return driver
def get_raw_trends_data(
driver: webdriver.Chrome, date_range: str, geo: str, query: str)
-> str:
url = f"https://trends.google.com/trends/explore?date={date_range}&geo={geo}&q={query}"
print(f"{url}에서 데이터 가져오기 중")
driver.get(url)
# 초기 429 오류 후 페이지 소스 가져오기 위한 우회 방법
driver.get(url)
driver.maximize_window()
# 페이지 로드 완료 대기
time.sleep(5)
return driver.page_source
get_raw_trends_data 메서드는 날짜 범위, 지역, 쿼리 이름을 매개변수로 받아 Chrome WebDriver를 사용하여 페이지 콘텐츠를 가져옵니다. URL이 처음 로드될 때 Google에서 발생하는 초기 429 오류를 해결하기 위한 우회 방법으로 driver.get 메서드가 두 번 호출된다는 점에 유의하세요.
다음 섹션에서 데이터를 가져오기 위해 이 메서드를 사용할 것입니다.
Beautiful Soup을 사용한 데이터 파싱
검색어에 대한 트렌드 페이지에는 ‘관심도(지역별)’ 위젯이 포함되어 있으며, 이 위젯에는 0에서 100 사이의 값을 가진 페이지 단위 기록이 포함되어 있어 위치별 검색어 인기도를 나타냅니다. 다음 코드 스니펫을 사용하여 Beautiful Soup으로 이 데이터를 파싱하세요:
# 임포트 추가
from bs4 import BeautifulSoup
def extract_interest_by_sub_region(content: str) -> dict:
soup = BeautifulSoup(content, "html.parser")
interest_by_subregion = soup.find("div", class_="geo-widget-wrapper geo-resolution-subregion")
related_queries = interest_by_subregion.find_all("div", class_="fe-atoms-generic-content-container")
# 추출된 데이터를 저장할 사전
interest_data = {}
# 지역명과 관심도 백분율 추출
for query in related_queries:
items = query.find_all("div", class_="item")
for item in items:
region = item.find("div", class_="label-text").text.strip()
interest = item.find("div", class_="progress-value").text.strip()
interest_data[region] = interest
return interest_data
이 코드 조각은 클래스 이름을 사용하여 하위 지역 데이터에 해당하는 div를 찾고, 결과를 반복하여 interest_data 사전(dictionary)을 구성합니다.
클래스 이름은 향후 변경될 수 있으므로, 정확한 이름을 찾기 위해Chrome 개발자 도구(DevTools)의요소검사기능을사용해야 할 수도 있습니다.
헬퍼 메서드를 정의했으니, 다음 코드 조각을 사용하여 “coffee”에 대한 데이터를 쿼리하세요:
# 매개변수
date_range = "now 7-d"
geo = "US"
query = "coffee"
# 원시 데이터 가져오기
driver = get_driver()
raw_data = get_raw_trends_data(driver, "now 7-d", "US", "coffee")
# 지역별 관심도 추출
interest_data = extract_interest_by_sub_region(raw_data)
# 추출된 데이터 출력
for region, interest in interest_data.items():
print(f"{region}: {interest}")
출력 결과는 다음과 같습니다:
하와이: 100
몬태나: 96
오리건: 90
워싱턴: 86
캘리포니아: 84
데이터 페이지 관리
위젯의 데이터는 페이지로 나누어져 있으므로, 이전 섹션의 코드 스니펫은 위젯의 첫 페이지 데이터만 반환합니다. 더 많은 데이터를 가져오려면 Selenium WebDriver를 사용하여 ‘다음’ 버튼을 찾아 클릭할 수 있습니다. 또한, 쿠키 동의 배너가 페이지의 다른 요소를 가리지 않도록 ‘동의’ 버튼을 클릭하여 처리해야 합니다.
쿠키 및 페이지 매김 처리를 위해 main.py 끝에 다음 코드 조각을 추가하세요:
# 임포트 추가
from selenium.webdriver.common.by import By
all_data = {}
# 쿠키 수락
driver.find_element(By.CLASS_NAME, "cookieBarConsentButton").click()
# 페이지네이션된 관심사 데이터 가져오기
while True:
# 추가 데이터가 있을 경우 md-button 클릭하여 로드
try:
geo_widget = driver.find_element(
By.CSS_SELECTOR, "div.geo-widget-wrapper.geo-resolution-subregion"
)
# 클래스명 "md-button" 및 aria-label "Next"를 가진 로드 버튼 찾기
load_more_button = geo_widget.find_element(
By.CSS_SELECTOR, "button.md-button[aria-label='Next']"
)
icon = load_more_button.find_element(By.CSS_SELECTOR, ".material-icons")
# 버튼의 클래스명에 arrow-right-disabled가 포함되는지 확인하여 비활성화 여부 검사
if "arrow-right-disabled" in icon.get_attribute("class"):
print("더 이상 로드할 데이터 없음")
break
load_more_button.click()
time.sleep(2)
extracted_data = extract_interest_by_sub_region(driver.page_source)
all_data.update(extracted_data)
except Exception as e:
print("더 이상 로드할 데이터가 없습니다", e)
break
driver.quit()
이 코드 조각은 기존 드라이버 인스턴스를 사용하여 클래스 이름과 일치하는 ‘다음’ 버튼을 찾아 클릭합니다. 요소에 'arrow-right-disabled' 클래스가 존재하는지 확인하여 버튼이 비활성화되었는지 판단합니다. 이는 위젯의 마지막 페이지에 도달했음을 의미합니다. 이 조건이 충족되면 루프를 종료합니다.
데이터 시각화
스크랩한 데이터에 쉽게 접근하고 추가 분석을 위해 추출된 하위 지역 데이터를 csv.DictWriter를 사용하여 CSV 파일에 저장할 수 있습니다.
먼저 main. py에서 save_interest_by_sub_region 함수를 정의하여 all_data 딕셔너리를 CSV 파일로 저장합니다:
# 추가 임포트
import csv
def save_interest_by_sub_region(interest_data: dict):
interest_data = [{"Region": region, "Interest": interest} for region, interest in interest_data.items()]
csv_file = "interest_by_region.csv"
# CSV 파일을 쓰기 모드로 열기
with open(csv_file, mode='w', newline='') as file:
writer = csv.DictWriter(file, fieldnames=["Region", "Interest"])
writer.writeheader() # 헤더 쓰기
writer.writerows(interest_data) # 데이터 쓰기
print(f"데이터가 {csv_file}에 저장되었습니다")
return csv_file
그런 다음pandas를사용하여 CSV 파일을DataFrame으로열고 특정 조건으로 데이터 필터링,그룹별작업으로 데이터 집계, 플롯을 통한 추세 시각화 등의 분석을 수행할 수 있습니다.
예를 들어, 하위 지역별 관심을 비교하기 위해 데이터를막대 차트로시각화해 보겠습니다. 플롯을 생성하려면 DataFrame과 원활하게 연동되는 Python 라이브러리인matplotlib를사용하세요.main.py파일에 다음 함수를 추가하여 막대 차트를 생성하고 이미지로 저장합니다:
# 임포트 추가
import pandas as pd
import matplotlib.pyplot as plt
def plot_sub_region_data(csv_file_path, output_file_path):
# CSV 파일에서 데이터 로드
df = pd.read_csv(csv_file_path)
# 지역별 비교를 위한 막대 그래프 생성
plt.figure(figsize=(30, 12))
plt.bar(df["Region"], df["Interest"], color="skyblue")
# 제목과 레이블 추가
plt.title('지역별 관심도')
plt.xlabel('지역')
plt.ylabel('관심도')
# 필요 시 x축 레이블 회전
plt.xticks(rotation=45)
# 플롯 출력
plt.savefig(output_file_path)
main.py 파일 끝에 다음 코드 조각을 추가하여 이전 함수를 호출합니다:
csv_file_path = save_interest_by_sub_region(all_data)
output_file_path = "interest_by_region.png"
plot_sub_region_data(csv_file_path, output_file_path)
이 코드 조각은 다음과 같은 플롯을 생성합니다:

이 튜토리얼의 모든 코드는이 GitHub 저장소에서 확인할 수 있습니다.
스크래핑의 어려움
이 튜토리얼에서는 Google Trends에서 소량의 데이터를 스크래핑했지만, 스크래핑 스크립트의 규모와 복잡성이 증가함에 따라 IP 차단이나 CAPTCHA 같은 문제에 직면할 가능성이 높습니다.
예를 들어, 이 스크립트를 사용하여 웹사이트에 더 빈번한 트래픽을 보낼 경우, 많은 웹사이트가 봇 트래픽을 감지하고 차단하기 위한 안전 장치를 갖추고 있기 때문에 IP 차단에 직면할 수 있습니다. 이를 피하려면 수동 IP 로테이션이나 최고의 프록시 서비스 중 하나를 사용할 수 있습니다. 어떤 프록시 유형을 사용해야 할지 확실하지 않다면, 웹 스크래핑에 가장 적합한 프록시 유형을 다루는 저희 글을 읽어보세요.
CAPTCHA 또는 reCAPTCHA는 웹사이트가 봇 트래픽이나 이상 징후를 감지하거나 의심할 때 흔히 사용하는 또 다른 도전 과제입니다. 이를 피하려면 요청 빈도를 줄이거나, 적절한 요청 헤더를 사용하거나, 이러한 문제를 해결할 수 있는 타사 서비스를 활용할 수 있습니다.
결론
이 글에서는 Selenium과 Beautiful Soup을 활용해 Python으로 Google 트렌드 데이터를 스크래핑하는 방법을 알아보았습니다.
웹 스크래핑 작업을 계속하다 보면 IP 차단이나 CAPTCHA 같은 문제를 마주칠 수 있습니다. 복잡한 스크래핑 스크립트를 관리하기보다는, Google 트렌드를 포함한 정확한 실시간 검색 엔진 데이터를 자동으로 수집하는 Bright Data의 SERP API를 사용하는 것을 고려해 보세요. SERP API는 동적 콘텐츠 처리, 지역 기반 타겟팅을 지원하며 높은 성공률을 보장하여 시간과 노력을 절약해 줍니다.
지금 가입하여 SERP API 무료 체험을 시작하세요!