자체 방문 통계는 항상 수집됩니다. 사용자가 공개 페이지를 어떻게 이용하는지 파악하는 데 쓰이는 Google Analytics(로그인한 워크스페이스는 제외)는 동의한 경우에만 사용됩니다. 자세한 내용은 개인정보 처리방침을 참고하세요.

Google 지도 리뷰를 스크래핑하는 방법: Places API, Python 또는 데이터 API

Places API는 장소당 리뷰를 최대 5개만 반환합니다. 세 가지 방법을 테스트해 리뷰 1,000개당 비용을 계산하고, CSV로 내보내는 Python 코드를 공유합니다.

지도 핀이 꽂힌 도시 블록을 그린 아이소메트릭 일러스트. 상점에서 리뷰 카드가 떠올라 청록색 컨베이어를 따라 트레이로 이동합니다. 트레이는 깔끔하게 정리된 리뷰 표 하나를 나타냅니다.

미국 텍사스주 오스틴의 한 치과는 Google 지도 등록 정보에 별점 4.6을 표시합니다. 그런데 최신 리뷰 200개의 평균은 4.305점이고, 그중 13%가 별 1개입니다. 공식 Places API로는 이 차이를 볼 수 없습니다. Places API는 장소당 리뷰를 관련성순으로 골라 최대 5개만 반환하기 때문입니다. 2026년 11월 2일, 저희는 Google 지도의 비즈니스와 리뷰를 가져오는 세 가지 방법을 테스트했습니다. 세 방법은 공식 Places API, 직접 만드는 Python 스크래퍼, 호출당 과금 데이터 API입니다. 이 가이드에서는 각 방법이 무엇을 반환하는지, 리뷰 1,000개당 비용이 얼마인지, 어디서 한계에 부딪히는지 보여 드립니다.

한 도시 블록으로 이어지는 세 갈래 길을 그린 일러스트입니다. 요금소, 공사 중인 도로, 리뷰 카드를 실은 청록색 컨베이어가 있습니다.
공식 API에는 상한이 있고, 직접 만든 스크래퍼는 유지보수가 필요하며, 호출당 과금 API는 요청마다 비용을 청구합니다.

리뷰 데이터의 중요성은 매달 커지고 있습니다. Google은 2026년 10월 8일 리뷰, 평점, 길찾기 요청을 바탕으로 한 첫 Fan-Favorite Dining Lists를 공개했습니다 [18]. 2026년 10월 21일에는 Google Maps가 Apple CarPlay에 Gemini 대화 기능을 추가했습니다 [19]. Search Engine Land가 인용한 Google의 수치에 따르면 Ask Maps는 500 million(5억) 명이 넘는 기여자의 리뷰를 활용할 수 있습니다 [20].

이제 더 많은 사람이 리뷰를 읽고 답을 내는 일을 AI에 맡깁니다. 그래서 AI가 어떤 리뷰를 읽는지, 최근 리뷰가 무엇을 말하는지가 중요합니다. 이 가이드가 최신순 리뷰와 관련성순 리뷰를 구분하는 이유입니다.

먼저 필요한 것부터 정하기

Google 지도 스크래핑 방법을 검색하는 사람들이 원하는 것은 제각각입니다. 영업팀은 한 대도시권에 있는 모든 치과의 이름, 전화번호, 웹사이트, 평점을 원합니다. 프랜차이즈 점주는 40개 지점의 모든 리뷰를 받아 불만에 빠르게 대응하고 싶어 합니다. 제품팀은 경쟁사가 지난 분기에 받은 별 1개 리뷰를 원합니다.

연구자는 한 지역 식당 500곳의 평점 분포를 원합니다. 이 중 비즈니스 목록이 필요한 작업은 첫 번째뿐입니다. 나머지 세 작업에는 리뷰가 필요하며, 필요한 리뷰 수, 기간, 등록 정보의 소유자에 따라 쓸 수 있는 방법이 달라집니다.

따라서 가격을 비교하기 전에 세 가지 질문에 답하십시오. 첫째, 장소당 리뷰가 몇 개 필요하며 5개로 충분합니까? 둘째, 해당 장소가 인증받은 자사 Google 비즈니스 프로필 지점입니까? 셋째, 팀에 브라우저 스크래퍼와 프록시 풀을 몇 년간 유지보수할 사람이 있습니까? 아래 순서도는 이 세 질문으로 방법을 나눕니다. 이어지는 각 섹션에서는 실제 요청으로 한 가지 방법을 테스트하거나 공식 문서를 한 줄씩 읽어 봅니다.

순서도입니다. 왼쪽의 질문 상자 3개는 장소당 리뷰 5개로 충분한지, 등록 정보를 소유하고 있는지, 스크래퍼를 유지보수할 수 있는지를 묻습니다. 각 질문에 '예'라고 답하면 각각 오른쪽의 공식 Places API, Business Profile API, 직접 만드는 Python 스크래퍼로 이어집니다. 세 질문에 모두 '아니요'라고 답하면 청록색 화살표를 따라 호출당 과금 데이터 API로 이어집니다.

많은 팀이 Business Profile API를 잊고 있어서 순서도에 포함했습니다. Google은 인증된 지점의 소유자에게 해당 지점의 리뷰를 모두 나열하는 API를 제공합니다 [11]. 평점순 또는 업데이트 시간순으로 정렬할 수 있으며 페이지당 최대 50개 리뷰를 반환합니다 [12]. OAuth 동의와 인증된 지점이 필요합니다.

경쟁사 리뷰는 읽을 수 없습니다. 아래 표는 네 가지 방법을 나란히 비교합니다. 각 칸의 내용은 이 가이드 뒷부분에서 테스트하거나 확인하는 사실입니다.

방법장소당 리뷰 수정렬과 페이지네이션리뷰 1,000개당 비용주요 비용
공식 Places API (Place Details)최대 5개관련성순만, 페이지네이션 없음무료 한도 내 $0, 이후 약 $5.00고정 상한, 작성자 표시 필수
Business Profile API자사 장소의 전체 리뷰평점 또는 업데이트 시간순, 페이지당 50개$0인증된 자사 지점만
브라우저 기반 Python 직접 구현페이지에 표시되는 만큼스크롤 시뮬레이션서버·프록시 비용 별도페이지 변경, 약관 위반 위험
EveryInfra 데이터 API정렬 기준당 400행, 호출당 100개최신순 또는 관련성순, 페이지 토큰호출당 100개 기준 $0.01389호출당 과금, 200행 초과 시 비동기

방법 1: 공식 Places API로 얻을 수 있는 것

Google부터 살펴보겠습니다. Places API (New)의 Place 리소스에는 reviews 필드가 있습니다. 레퍼런스 문서는 이 필드를 관련성순으로 정렬된 장소 리뷰 목록이라고 설명합니다. 또한 리뷰를 최대 5개까지 반환할 수 있다고 명시합니다 [1]. 이 상한은 요금 등급과 관계없이 같습니다. 리뷰용 페이지 토큰도 없습니다. 저희는 해당 문구를 스크린샷으로 찍어 청록색 상자로 표시했습니다.

Google Maps Platform Places API 레퍼런스 페이지 스크린샷입니다. Place 리소스 필드 목록의 reviews 행에 청록색 상자가 표시되어 있습니다. 목록은 관련성순으로 정렬되며 리뷰를 최대 5개까지 반환할 수 있다고 적혀 있습니다.
2026년 11월 2일에 확인한 Places API 레퍼런스 스크린샷입니다. reviews 필드 설명에 최대 5개, 관련성순 정렬이라고 나와 있습니다. Google Maps Platform 문서

요청은 간단합니다. Place Details (New)는 경로에 장소 ID를, 헤더에 필수 필드 마스크를 넣는 GET 요청입니다 [2]. 필드 마스크는 받고 싶은 필드를 Google에 알려 줍니다. 아래는 공식 문서를 바탕으로 한 설정 예시입니다. Google API 키로 직접 실행하지는 않았습니다.

bash
# Configuration example (not run): rating, review count and up to 5 reviews for one place
curl -s "https://places.googleapis.com/v1/places/ChIJl6T2cnbMRIYR7eD538S3oWU" \
  -H "X-Goog-Api-Key: $GOOGLE_MAPS_API_KEY" \
  -H "X-Goog-FieldMask: displayName,rating,userRatingCount,reviews"

필드 마스크가 청구액을 결정합니다. Google은 각 요청에 마스크에 포함된 필드 중 가장 비싼 필드의 SKU 요금을 적용합니다. reviews 필드는 Place Details Enterprise + Atmosphere SKU에 속하므로 리뷰를 요청하면 모두 이 요금이 적용됩니다 [3][5]. 2025년 3월 1일, Google은 기존 월 $200 크레딧을 SKU별 무료 사용 한도로 대체했습니다.

월 무료 한도는 Essentials SKU 10,000회, Pro SKU 5,000회, Enterprise SKU 1,000회입니다 [4]. 저희는 2026년 11월 2일에 가격표를 확인했습니다. 결제 개요 페이지에는 2026-10-30에 마지막으로 업데이트되었다고 적혀 있습니다 [4]. 아래 표는 이 가이드와 관련된 행을 요청 1,000건당 미국 달러 기준으로 보여 줍니다.

SKU (Places API New)월 무료 사용량100K까지100K~500K500K~1M1M~5M5M 초과
Place Details Pro5,000$17.00$13.60$10.20$5.10$1.28
Place Details Enterprise1,000$20.00$16.00$12.00$6.00$1.51
Place Details Enterprise + Atmosphere (리뷰 포함)1,000$25.00$20.00$15.00$7.50$2.28
Text Search Pro5,000$32.00$25.60$19.20$9.60$2.40
Text Search Enterprise + Atmosphere1,000$40.00$32.00$24.00$12.00$3.40

이 표에 따르면 Place Details 호출 1건의 비용은 $0.025이며, 리뷰는 최대 5개까지 받을 수 있습니다. 첫 유료 구간 기준으로 리뷰 1,000개당 $5.00입니다. 월 500만 건을 넘으면 요금이 호출 1,000건당 $2.28로 내려가지만, 이 역시 리뷰 1,000개당 $0.456입니다. 무료 한도도 중요합니다. 매달 장소 1,000곳에서 리뷰를 5개씩 받으면 되는 경우라면 공식 API는 비용이 들지 않습니다. 이 경우는 공식 API가 더 나은 선택인 경우를 다루는 섹션에서 다시 설명합니다.

로그 스케일 가로 막대 차트입니다. 리뷰 1,000건당 비용을 미국 달러로 보여 줍니다. Places API의 첫 유료 구간은 $5.00입니다. 호출 5M건 초과 구간의 Places API 요금은 $0.456입니다. 호출당 리뷰 100건 기준 EveryInfra 리뷰 호출은 $0.01389이며 청록색으로 강조되어 있습니다.

저장하고 표시할 수 있는 범위는 세 가지 사용 규칙으로도 정해집니다. 첫째, Places API 정책에 따르면 각 리뷰에 작성자 정보(사진, 이름, 프로필 링크)를 함께 표시해야 합니다 [7]. 둘째, 장소 ID는 장기간 저장할 수 있지만 그 밖의 콘텐츠는 대부분 캐시할 수 없습니다. 즉 공식 API 결과로 자체 장기 리뷰 데이터베이스를 구축할 수 없습니다 [7]. Google은 12개월이 지난 장소 ID는 갱신하는 것이 좋다고도 안내합니다 [8]. 셋째, 리뷰는 항상 관련성 순으로 정렬됩니다.

세 번째 규칙은 개발자 포럼에서 가장 흔한 불만입니다. 2016년 Stack Overflow 질문은 Places API에서 리뷰를 5개보다 많이 가져오는 방법을 묻습니다 [39]. 2019년 질문은 최신 리뷰를 가져오는 방법을 묻습니다 [40]. 두 스레드 모두 리뷰는 최대 5개라는 같은 결론에 이릅니다. r/learnpython의 Reddit 스레드도 초보자 입장에서 같은 질문을 합니다 [41]. 새 API 버전이 나온 뒤에도 답은 달라지지 않았습니다.

2025년 5월 8일부터 Places API는 Gemini가 작성한 리뷰 요약도 반환할 수 있습니다 [9][10]. 요약은 원시 데이터가 아니므로 이를 바탕으로 별점을 집계할 수는 없습니다.

경로 2: 직접 만드는 Python 스크래퍼와 그 한계

Python으로 Google Maps를 스크래핑하는 튜토리얼 중 상당수는 requests와 BeautifulSoup으로 시작합니다. 저희는 2026년 11월 2일 00:19:50(SGT)에 이 첫 단계를 시도했습니다. Python 표준 라이브러리로 싱가포르의 한 식당 지도 페이지에 일반 HTTP GET 요청을 1건 보냈습니다. 상태 코드는 200이었고, 페이지 크기는 210,679바이트, script 태그는 12개였습니다.

페이지 제목은 "Google Maps"뿐이었습니다. 식당 이름은 저희가 보낸 URL이 그대로 반영된 부분에만 나타났습니다. 리뷰 수 8,226도 페이지에 없었습니다. API로 받은 리뷰 스니펫 20개 중 페이지에 있는 것은 하나도 없었습니다.

즉 리뷰는 브라우저에서 JavaScript가 실행된 뒤에야 로드됩니다. 직접 만드는 스크래퍼는 Playwright 같은 브라우저 자동화를 써야 합니다 [37]. 아래 스케치는 일반적인 구조입니다. 장소 페이지를 열고, 리뷰 탭을 클릭하고, 리뷰 패널을 스크롤한 다음 페이지 요소에서 텍스트를 읽습니다. Google Maps 페이지를 대량으로 자동 스크래핑하면 서비스 약관을 위반하므로 이 코드는 실행하지 않았습니다. 어떤 작업이 필요한지 보여 주려고 실었을 뿐입니다.

python
# Configuration example (not run): the usual structure of a browser review scraper
from playwright.sync_api import sync_playwright

PLACE_URL = "https://www.google.com/maps/place/?q=place_id:ChIJl6T2cnbMRIYR7eD538S3oWU&hl=en"

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page(locale="en-US")
    page.goto(PLACE_URL, wait_until="networkidle")
    page.get_by_role("tab", name="Reviews").click()          # breaks when the label changes
    panel = page.locator("div[role='feed']")                  # a guessed selector that changes often
    for _ in range(30):                                       # about 10 more reviews per scroll
        panel.evaluate("el => el.scrollBy(0, el.scrollHeight)")
        page.wait_for_timeout(1200)
    texts = page.locator("[data-review-id] span").all_inner_texts()
    print(len(texts))
    browser.close()

이 스케치의 모든 줄은 페이지가 바뀌지 않는다는 가정에 기대고 있습니다. 탭 이름, 패널 셀렉터, 스크롤당 리뷰 수, 페이지 언어가 모두 바뀔 수 있습니다. Google의 프런트엔드 릴리스 한 번이나 사용 중인 IP 주소에 표시되는 인증 페이지 하나만으로도 스크립트가 멈춥니다. 이런 유지보수 부담을 가늠하기 위해 GitHub에서 별이 가장 많은 오픈소스 Google Maps 스크래퍼 중 하나를 살펴봤습니다 [32]. 2026년 11월 2일 기준 별 7,148개, 포크 1,112개, MIT 라이선스였고, 마지막 푸시는 2026년 10월 21일이었습니다.

이 프로젝트는 2026년 7월 13일부터 9월 20일까지 v1.16.3부터 v1.18.1까지 8개 릴리스를 냈습니다 [36]. 8월 1일 이후 열린 이슈는 15개입니다. 표에는 리뷰와 관련되거나 작업을 멈추게 하는 이슈를 정리했습니다. 제목은 의역했으며 링크는 참고 자료에 있습니다 [33][34][35].

날짜이슈사용자 보고 내용상태
2026-09-01#327추가 리뷰 옵션이 리뷰를 약 10개만 반환하고, 내부 리뷰 엔드포인트가 403을 반환함(v1.17.4)열림
2026-09-23#331실행 중 스크래핑 엔진 오류가 다수 발생닫힘
2026-10-05#337v1.18.0 업그레이드 후 웹 작업 목록이 비어 있고 시작 버튼이 동작하지 않음열림
2026-10-06#338브라우저 페이지 또는 컨텍스트가 닫혀 모든 스크래핑 작업이 실패열림
2026-10-09#341제목: "300 Reviews per place"열림
2026-10-22#346브라우저 컨텍스트가 닫히지 않아 웹 작업이 작업 중 상태로 남음열림

코드 품질을 지적하려는 것이 아닙니다. 별 7,000개에 10주 동안 릴리스를 8개 낸 프로젝트도 몇 주마다 "리뷰 10개만"과 "모든 작업 실패" 문제를 겪습니다. 원인은 부실한 코드가 아니라 Google 쪽의 변경입니다. 이슈 #337과 #346 [42][43]은 다른 종류의 비용을 보여 줍니다. 이 두 이슈는 Google과 관련이 없고 브라우저 자동화 자체에서 생긴 문제입니다.

몇 달씩 돌아가는 리뷰 스크래퍼는 주말에 짜는 스크립트가 아니라 온콜 담당자가 필요한 작은 서비스입니다. 브라우저 시작과 종료, 메모리, 동시 요청 수, 타임아웃, 프록시, 출구 IP 주소를 모두 관리해야 합니다. 직접 만들면 문제를 먼저 발견해 주는 커뮤니티도 잃게 됩니다. 호출당 가격과 비교하기 전에 이 작업에 드는 비용부터 예산에 넣으세요.

직접 만든 스크래퍼는 robots.txt도 무시합니다. 저희는 같은 시각에 google.com/robots.txt를 내려받았습니다 [16]. 86번째 줄에는 Disallow: /maps/, 74번째 줄에는 Disallow: /maps?가 있습니다. 이 파일에는 /maps/place/와 /maps/search/에 대한 Allow 줄도 있습니다.

RFC 9309에 따르면 가장 길게 일치하는 규칙이 우선하므로 일반적인 장소 페이지 경로는 허용됩니다. /maps/ 아래의 다른 경로 중 Allow 줄이 없는 경로는 Disallow 규칙에 해당합니다 [17]. RFC 9309는 robots 규칙이 접근 권한을 부여하는 수단이 아니라는 점도 명시합니다 [17]. 실제 제한은 서비스 약관입니다.

약관, 판례, 개인정보

먼저 계약부터 보겠습니다. Google Maps Platform 고객이라면 플랫폼 약관 3.2.3(a)항의 제목이 "No Scraping"입니다. 이 조항은 고객이 서비스 외부에서 사용할 목적으로 Google Maps 콘텐츠를 내보내거나 추출하거나 그 밖의 방식으로 스크래핑해서는 안 된다고 규정합니다 [13]. 일반 사용자에게는 Google Maps 추가 약관이 콘텐츠의 대량 다운로드와 대량 피드를 금지합니다 [14]. Google은 이 약관을 2026년 1월 27일에 마지막으로 수정했습니다. 이 약관은 Google Maps를 이용해 다른 지도 데이터 세트를 만들거나 보강하는 것도 금지하며, 업체 정보 데이터베이스도 그 대상에 포함됩니다 [14].

따라서 공식 API든 직접 만든 스크래퍼든 Google 콘텐츠의 사본을 만드는 것은 허용되지 않습니다. 미국 법원은 더 넓은 쟁점을 다뤘습니다. 2022년 4월 18일 제9연방항소법원은 hiQ Labs v. LinkedIn 사건에서 공개 웹 데이터 스크래핑은 컴퓨터 사기 및 남용 방지법(CFAA)상 "권한 없는" 접근에 해당하지 않을 가능성이 높다고 판단했습니다 [21].

2024년 1월 23일 캘리포니아 북부 연방지방법원은 Meta Platforms가 제소한 데이터 수집 회사에 유리한 약식판결을 내렸습니다(사건번호 3:23-cv-00077). 법원은 Meta가 자사 약관이 로그아웃 상태에서의 공개 데이터 스크래핑을 금지한다는 점을 입증하지 못했다고 판단했습니다 [22].

이 두 판결은 공개 데이터 스크래핑이 합법이라는 근거로 자주 인용됩니다. 하지만 두 판결은 특정 계약 문구에 관한 특정 법적 쟁점에 답한 것입니다. 약관 위반에 대가가 없다고 말하지 않으며, 미국 밖에는 적용되지 않습니다. 이 가이드는 법률 자문이 아닙니다. 상업적으로 사용하기 전에 변호사와 상담하세요.

다음은 개인정보입니다. 리뷰 작성자의 이름, 사진, 프로필 링크는 개인정보입니다. 캘리포니아에서는 캘리포니아 소비자 개인정보 보호법(CCPA)이 기업이 수집한 데이터에 대한 소비자의 권리를 보장합니다. 캘리포니아 법무장관실은 2026년 8월 28일 CCPA 페이지를 업데이트했습니다 [23]. 유럽연합에서는 GDPR이 적용됩니다 [24].

싱가포르에는 개인정보보호법(PDPA)이 있고 [25][26], 멕시코는 2025년 3월 20일 새 연방 개인정보 보호법을 공포했습니다 [27]. 대부분의 분석에는 리뷰 작성자의 신원이 필요하지 않습니다. 평점, 날짜, 텍스트, 업체 답글은 남기고 이름과 사진은 제외하세요. 아래 CSV 내보내기 스크립트가 그렇게 처리합니다.

다른 업체의 리뷰를 자사 페이지에 옮겨 게시하면 허위 참여에 관한 Google의 콘텐츠 제공 정책도 적용됩니다 [15].

경로 3: 호출당 과금 데이터 API

세 번째 경로는 호출당 과금 데이터 API입니다. 요청을 1건 보내면 서비스가 구조화된 업체 데이터나 리뷰 데이터를 반환합니다. 브라우저, 프록시, 페이지 변경은 서비스가 처리하고, 요금은 호출 단위로 부과됩니다. 이 시장에는 과금 모델이 여러 가지 있습니다. 결과 건당 과금하는 클라우드 스크래핑 플랫폼, 쿼리당 과금하는 검색 결과 API, 호출당 과금하는 데이터 API가 대표적입니다. EveryInfra는 마지막 모델을 사용합니다.

이 가이드는 업체별 가격 비교표가 아니라 튜토리얼입니다. 호출 방법, 데이터 형태, 실패하는 지점에 초점을 맞춥니다. EveryInfra의 단가와 과금 단위는 Google Maps Reviews API 페이지에서 확인하세요.

EveryInfra의 Google Maps Reviews API는 네 가지 기능을 제공합니다. google_maps_reviews/search는 키워드와 위치로 장소를 찾습니다. google_maps_reviews/profile은 장소 한 곳의 상세 정보를 반환합니다. google_maps_reviews/reviews는 장소 한 곳의 리뷰를 반환합니다. google_maps_reviews/contributor_reviews는 리뷰 작성자 한 명이 쓴 리뷰를 반환합니다.

2026년 11월 2일 00:14:03(SGT)에 공개 카탈로그를 확인했습니다. 네 가지 기능 모두 호출당 $0.001389입니다. Search는 호출당 최대 50곳, 페이지를 넘겨 최대 120행까지 반환합니다. Reviews는 호출당 리뷰 최대 100개, 페이지를 넘겨 최대 400행까지 반환합니다.

동기 요청으로는 200행까지 가져올 수 있고, 그보다 깊은 페이지는 비동기 작업이 필요합니다. 리뷰 정렬 순서는 newest와 relevance 두 가지입니다. since 파라미터는 특정 날짜 이후의 리뷰로 결과를 제한하고, lang은 리뷰 언어를 지정합니다.

다음은 오스틴 치과에 대한 리뷰 요청 예시입니다. 장소 ID가 포함된 Google Maps 장소 URL이 장소를 지정하는 가장 안정적인 방법입니다.

bash
curl -s https://api.everyinfra.com/api/v1/social \
  -H "Authorization: Bearer $EVERYINFRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"platform":"google_maps_reviews","action":"reviews",
       "params":{"url":"https://www.google.com/maps/search/?api=1&query=Swish%20Dental%20-%20Domain&query_place_id=ChIJl6T2cnbMRIYR7eD538S3oWU",
                 "sort":"newest","limit":100}}'

이 요청은 00:20:36(SGT)에 보냈습니다. 리뷰 100개가 반환되었고 billing.charged_usd는 0.001389였습니다. 응답에는 pagination.has_more가 true로 설정되어 있었고 next_page_token도 있었습니다. 다음 페이지를 받으려면 같은 요청의 page_token에 그 토큰을 받은 그대로 넣어 보내세요. 아래 스크린샷은 00:15(SGT)에 싱가포르 식당에 대해 받은 실제 응답이며, 리뷰 작성자 이름은 가렸습니다.

어두운 코드 카드에 표시된 API 응답 스크린샷입니다. 헤더에는 POST /api/v1/social, google_maps_reviews/reviews, 2026-11-02 00:15 SGT가 표시되어 있습니다. 가려진 리뷰 레코드 2개 위에 count 100과 charged_usd 0.001389가 청록색 상자로 표시되어 있습니다.
리뷰 작성자 이름을 가린 실제 응답 발췌입니다. 호출 1건으로 리뷰 100개를 받았고 $0.001389가 과금되었습니다. EveryInfra API 실제 응답

각 리뷰 레코드에는 카탈로그에 나열된 필드가 있습니다. 표에는 분석에 가장 중요한 필드와 오스틴 최신 리뷰 200개 기준 집계를 정리했습니다. 이 중 detailed_rating과 owner_response는 공식 Places API 리뷰 객체에 없는 필드입니다.

필드의미오스틴 최신 리뷰 200개 기준
rating별 1~5개200개 중 200개
posted_at게시 시각(UTC)200개 중 200개
text리뷰 텍스트(비어 있을 수 있음)130개에 텍스트 있음(65%)
owner_response, owner_response_at업체 답글과 답글 시각146 (73%)
detailed_rating음식, 서비스 등 세부 점수이 치과는 0개
image_urls리뷰에 첨부된 사진3
is_local_guide, reviewer_review_count지역 가이드 여부와 작성자의 리뷰 수58개는 지역 가이드가 작성
like_count"도움이 됨" 투표 수200개 중 200개
id, url, place_id리뷰 및 장소 식별자200개 중 200개

00:20:02(SGT)에 보낸 프로필 호출 google_maps_reviews/profile은 치과의 상세 정보를 반환했습니다. 별점 4.6, 리뷰 1,659개, 주소, 전화번호, 웹사이트, 영업시간, 좌표입니다. 00:17:10(SGT)에 보낸 검색 호출 google_maps_reviews/search에는 키워드 "dentist"와 위치 "Austin, TX"를 사용했습니다. 1페이지에서 50곳이 반환되었습니다.

2페이지는 51행부터 시작하므로 00:23:59(SGT)의 동기 요청은 비동기 모드를 요구하는 422를 반환했습니다. 00:24:22(SGT)의 비동기 작업은 50곳을 더 반환했습니다. 장소 ID로 중복을 제거하니 서로 다른 치과 100곳이 남았고, 그중 99곳의 주소가 오스틴이었습니다. 영업 리드 목록이 목적이라면 이것으로 작업이 끝납니다. 여러 검색 결과를 합칠 때는 장소 ID 중복 제거 가이드를 참고하세요.

테스트 1: 오스틴 치과의 업체 정보 별점과 최근 별점 비교

이 테스트는 미국 소비자에게 중요한 질문 하나에 답합니다. 업체 정보에 표시된 별점으로 치과의 현재 상태를 알 수 있을까요? 오스틴 Domain 지역에 있는 Swish Dental의 최신 리뷰 200개를 00:20:36과 00:23:41(SGT)에 두 페이지로 나눠 가져왔습니다. 업체 정보에는 리뷰 1,659개, 별점 4.6이 표시되어 있습니다.

최신 리뷰 200개의 평균 별점은 4.305점으로, 업체 정보의 별점보다 약 0.3점 낮습니다. 5점 리뷰가 156개, 4점 리뷰가 7개, 3점 리뷰가 5개, 2점 리뷰가 6개, 1점 리뷰가 26개입니다. 1점 리뷰는 표본의 13%입니다. 치과는 리뷰 200개 중 146개에 답글을 달았으므로, 누군가 리뷰를 관리하고 있는 것이 분명합니다.

환자, 투자자, 경쟁사에게는 전체 평점보다 최신 리뷰 200개가 더 많은 정보를 줍니다. 업체 정보의 평점은 여러 해에 걸친 평가를 합산한 값입니다. 최근 1점 리뷰가 몰려 있다면 직원, 접수 창구, 수납 쪽에 변화가 있었다는 뜻일 수 있습니다. 공식 Places API는 관련성 기준으로 고른 리뷰 5개만 주기 때문에 이런 쏠림을 보여 줄 수 없습니다.

텍스트에서는 또 다른 이야기가 보입니다. 별 1개 리뷰 26개 중 24개(92%)에 텍스트가 있고, 길이 중앙값은 361.5자입니다. 별 5개 리뷰 156개 중에서는 89개(57%)에만 텍스트가 있고 중앙값은 119자입니다. 불만이 있는 환자는 이유를 설명합니다.

만족한 환자는 별점만 남기는 경우가 많습니다. 텍스트가 있는 리뷰만 분석하면 부정적인 리뷰에 더 큰 가중치를 주게 됩니다. 별점만 분석하면 불만 내용에 담긴 유용한 세부 정보를 놓칩니다.

그룹 막대 차트입니다. 장소 3곳의 업체 정보 평점과 최신 리뷰의 평균 별점을 비교합니다. 싱가포르 식당은 업체 정보 평점 4.4와 최신 리뷰 300개의 평균 별점 4.65, 오스틴 치과는 4.6과 최신 리뷰 200개의 평균 별점 4.305, 멕시코시티 타케리아는 4.2와 최신 리뷰 200개의 평균 별점 4.275입니다. 최신 리뷰 막대는 청록색입니다.

테스트 2: 관련성 상위 리뷰 5개와 최근 리뷰 300개 비교

두 번째 테스트는 리뷰 5개 한도가 장소에 대한 인상을 어떻게 바꾸는지 보여 줍니다. 싱가포르 11 New Bridge Road에 있는 Song Fa Bak Kut Teh를 사용했습니다. 업체 정보에는 별점 4.4, 리뷰 8,226개, 사진 18,685장이 표시됩니다. 00:16:10(SGT)에 관련성 순 상위 리뷰 100개를 가져왔습니다.

최신 리뷰 300개도 세 페이지에 걸쳐 가져왔습니다. 1페이지와 2페이지는 00:15:29와 00:16:42(SGT)에 동기 호출로, 3페이지는 00:18:27(SGT)에 비동기 작업으로 받았습니다. 관련성 순 상위 5개는 공식 API가 반환하는 리뷰 5개를 대신하는 것으로 봤습니다.

상위 5개의 평균 별점은 4.8점입니다. 5개 모두 텍스트와 사진이 있고, 텍스트 길이 중앙값은 517자입니다. 작성자 5명 모두 지역 가이드이고, 작성 날짜는 2026년 4월부터 7월 사이입니다. 관련성 순 상위 100개의 평균 별점은 4.5점이고, 모두 텍스트가 있으며 길이 중앙값은 357자입니다. 날짜는 2016년부터 2026년 9월까지 걸쳐 있습니다. 최신 300개의 평균 별점은 4.65점이고, 텍스트가 있는 비율은 63%뿐이며 길이 중앙값은 67자입니다.

싱가포르 식당 한 곳의 리뷰 세트 4개에 대한 평균 별점을 나타낸 점도표입니다. 업체 정보 평점은 리뷰 8,226개 기준 4.4이고, 관련성 상위 5개는 4.8, 관련성 상위 100개는 4.5, 최신 300개는 4.65입니다. 축 범위는 4.0~5.0이며, 상위 5개 점은 청록색입니다.

Google은 관련성 산정 방식을 공개하지 않습니다. 데이터를 보면 활발한 리뷰 작성자가 쓴 사진 포함 장문 리뷰를 뚜렷하게 선호하며, 이런 리뷰는 긍정적인 경향이 있습니다. 공식 API의 리뷰 5개로 장소를 판단하면 최근 고객의 평균적인 반응이 아니라 대표성이 높다고 선택된 긍정적 리뷰를 보게 됩니다. 관련성 상위 100개와 최신 300개가 겹치는 리뷰는 21개뿐이므로 사실상 서로 다른 표본입니다.

텍스트가 있는 리뷰의 텍스트 길이 중앙값 막대 차트입니다. 관련성 상위 5개 517자, 관련성 상위 100개 357자, 최신 300개 67자입니다. 레이블에는 텍스트가 있는 비율(100%, 100%, 63%)이 표시됩니다.

텍스트가 없는 리뷰는 놓치기 쉽습니다. 최신 300개 중 111개(37%)는 별점만 있고 글이 없습니다. 키워드 분석이나 감성 분석에서는 이 37%가 빈 데이터입니다. 별점 추세 분석에서는 이 37%가 장문 리뷰 작성자의 편향을 받지 않는 부분입니다. 두 분석에 필요한 데이터가 다르므로, 리뷰 API는 요약만이 아니라 별점과 텍스트를 모두 반환해야 합니다.

테스트 3: 멕시코시티 타케리아와 위치 함정

세 번째 장소는 멕시코시티 코요아칸의 Tacos Chupacabras입니다. 업체 정보에는 별점 4.2, 리뷰 18,361개, 가격대 MXN 100~200이 표시됩니다. 00:23:05와 00:23:24(SGT)에 lang: es419로 최신 리뷰 200개를 가져왔습니다. 평균 별점은 4.275점으로 업체 정보에 표시된 평점과 비슷합니다. 5점 리뷰는 121개, 4점 리뷰는 42개, 3점 리뷰는 21개, 2점 리뷰는 3개, 1점 리뷰는 13개입니다. 텍스트가 있는 리뷰는 55.5%뿐이고, 길이 중앙값은 69자이며, 업체는 어떤 리뷰에도 답글을 달지 않았습니다.

세 장소를 나란히 놓으면 분포 모양이 다릅니다. 치과는 5점과 1점 리뷰가 많고 중간 점수는 적습니다. 타케리아는 3점과 4점 리뷰가 더 많은데, 전형적인 "음식은 훌륭하지만 줄이 길다" 패턴입니다. 평균 하나로는 두 분포가 모두 가려집니다.

최신 리뷰의 별점 구성을 보여 주는 100% 누적 막대 차트입니다. 싱가포르 리뷰 300개: 5점 리뷰 228개, 4점 리뷰 52개, 3점 리뷰 13개, 2점 리뷰 1개, 1점 리뷰 6개. 오스틴 리뷰 200개: 5점 리뷰 156개, 4점 리뷰 7개, 3점 리뷰 5개, 2점 리뷰 6개, 1점 리뷰 26개. 멕시코시티 리뷰 200개: 5점 리뷰 121개, 4점 리뷰 42개, 3점 리뷰 21개, 2점 리뷰 3개, 1점 리뷰 13개.

멕시코시티 검색에서는 위치 파라미터의 문제도 드러났습니다. 00:17:32(SGT)에 위치를 "Ciudad de México"로 지정해 "taquería"를 검색했습니다. 결과 50개 모두 멕시코에 있었지만 멕시코시티에 있는 곳은 1개뿐이었습니다. 나머지 49개는 다른 11개 주에 있었습니다. 사카테카스 14개, 누에보레온 7개, 치와와 6개, 할리스코 6개였습니다.

00:19:39(SGT)에는 키워드에 장소를 넣어 "taquería en Coyoacán, Ciudad de México"로 검색했습니다. 결과 50개 모두 멕시코시티였고, 그중 47개가 코요아칸에 있었습니다. 오스틴 검색에는 위치 "Austin, TX"를 사용했습니다. 결과 100개 중 99개가 오스틴이었고, 나머지 1개는 오스틴과 붙어 있는 웨스트레이크힐스에 있었습니다.

원인은 아직 모릅니다. 두 요청은 여러 면에서 다릅니다. 멕시코시티 호출에는 language: es도 함께 보냈고, 오스틴 위치에는 주 코드가 들어 있었습니다. 테스트 한 쌍으로는 어떤 차이가 영향을 주는지 알 수 없습니다. 원인을 알기 전까지는 도시, 가능하면 구까지 키워드에 넣으세요. 먼저 검색 1페이지만 실행해 대상 도시에 있는 결과가 몇 개인지 세어 보세요.

검색 결과 중 대상 도시 안에 있는 비율을 보여 주는 막대 차트입니다. 위치 파라미터를 쓴 멕시코시티: 50개 중 1개. 키워드에 장소를 넣은 멕시코시티: 50개 중 50개. 위치 파라미터를 쓴 오스틴: 100개 중 99개. 키워드 막대는 청록색입니다.

최신순 정렬은 엄밀한 날짜순이 아닙니다

리뷰를 모니터링하는 팀은 흔히 같은 루프를 작성합니다. 최신순으로 정렬해 한 페이지를 읽고, 마지막으로 저장한 리뷰보다 오래된 리뷰가 처음 나오면 멈춥니다. 저희는 최신순으로 정렬한 세트 3개의 모든 행을 확인했습니다. 바로 위 행보다 게시 시각이 늦은 행을 순서가 어긋난 행으로 봤습니다. 싱가포르는 300개 중 6개, 멕시코시티는 200개 중 18개, 오스틴은 200개 중 50개(25%)였습니다. 싱가포르 세트에는 2026년 페이지에 2023년 리뷰 2개가 섞여 있기도 했습니다.

최신순으로 정렬한 리뷰에서 날짜 순서가 어긋난 행 수를 보여 주는 막대 차트입니다. 싱가포르 300개 중 6개, 멕시코시티 200개 중 18개, 오스틴 200개 중 50개(25%).

이 현상은 API가 아니라 Google Maps 자체에서 비롯됩니다. 수정된 리뷰나 업체 답글이 새로 달린 리뷰는 날짜 순서와 다르게 나타날 수 있습니다. 영향은 실제로 있어서, "처음 오래된 리뷰가 나오면 멈추는" 루프는 데이터를 놓칠 수 있습니다. 해결 방법은 두 가지입니다. 멈추기 전에 한 페이지를 더 읽거나, since를 사용해 특정 날짜 이후의 리뷰만 받으세요. 그런 다음 posted_at 기준으로 직접 다시 정렬하세요. 아래 CSV 내보내기 스크립트는 마지막 단계에서 다시 정렬합니다.

실패와 환불: 실제 오류는 어떤 모습일까

호출당 과금에서 가장 걱정되는 것은 실패한 호출에도 요금이 부과되는 상황입니다. 테스트 중 일부는 의도적으로, 일부는 실수로 여섯 가지 오류를 일으켰습니다. 표에는 API가 반환한 그대로 정리했습니다. 모든 시각은 2026년 11월 2일 SGT 기준입니다.

시각(SGT)수행한 작업응답과금응답이 안내한 다음 단계
00:15:561페이지 직후 2페이지 요청, 분당 10건 초과429 rate_limited, retry_after 4초없음대기 후 재시도
00:16:03빈 페이지 토큰을 다시 보냄422 invalid_page_token없음next_page_token을 받은 그대로 다시 보냄
00:17:00동기 모드로 리뷰 3페이지 요청(200행 초과)422 async_required없음"mode":"async"를 추가하고 작업을 폴링
00:20:55since를 미래 날짜인 2026-11-30으로 설정200, 리뷰 0개, empty_result_refunded환불, $0없음
00:21:38지도 페이지가 아닌 URL을 보냄503, 재시도 가능, retry_after 20초환불, $03회 중 1번째 실패라고 안내
00:22:07sort를 oldest로 설정422 invalid_value, 허용 값은 newest와 relevance없음sort만 바꿔 다시 전송

이 중 하나는 개선이 필요합니다. 잘못된 URL을 보내면 잘못된 파라미터를 알려 주는 422 대신 재시도 가능한 503이 반환됩니다. 요금은 부과되지 않지만, 503마다 세 번씩 재시도하는 클라이언트는 결과 없이 약 1분을 기다리게 됩니다. 나머지 다섯 가지 오류는 문서와 일치합니다. 파라미터 오류와 요청 속도 제한에는 요금이 없고, 빈 결과는 환불되며, 각 오류 메시지에는 허용 값과 다음 단계가 나와 있습니다.

URL 문제는 직접 작성한 코드에서 검사하는 것으로 충분합니다. 이 가이드의 모든 장소 링크는 https://www.google.com/maps/로 시작합니다:

python
if not url.startswith("https://www.google.com/maps/"):
    raise ValueError("not a Google Maps place link")

비동기 작업의 과금 시점에 주의하세요. 결과를 가져갈 때가 아니라 작업을 제출할 때 과금됩니다. 00:18:27(SGT)에 싱가포르 3페이지 비동기 작업을 제출했는데, 제출 응답에 이미 charged_usd 0.001389가 표시되었습니다. 작업 상태는 running, finalizing, succeeded 순으로 바뀌었고 리뷰 100개를 받았습니다. 비동기 작업이 실패하면 동일한 과금 ID로 결제된 금액이 환불됩니다.

Python으로 Google Maps 리뷰를 CSV로 내보내기

아래 코드는 Google Maps 리뷰를 스크래핑하는 방법에 대한 간단한 답입니다. Google Maps 장소 링크 하나를 넘기면 최신 리뷰를 페이지 단위로 읽어 CSV로 저장합니다. Python 표준 라이브러리만 사용합니다. 요청 속도 제한, 비동기 처리가 필요한 깊은 페이지, 페이지 토큰을 처리하고, 마지막에 게시 시각 기준으로 정렬하며, 리뷰 작성자 이름은 파일에 넣지 않습니다.

python
"""Export Google Maps reviews of one place to CSV via EveryInfra.
usage: EVERYINFRA_API_KEY=... python3 export_reviews_csv.py "<google maps place url>" reviews.csv [max_pages]
"""
import csv, json, os, sys, time, urllib.request, urllib.error

API = "https://api.everyinfra.com"
KEY = os.environ["EVERYINFRA_API_KEY"]
FIELDS = ["id", "place_name", "rating", "posted_at", "text", "owner_response",
          "owner_response_at", "like_count", "is_local_guide", "reviewer_review_count", "url"]

def call(method, path, body=None):
    req = urllib.request.Request(API + path, method=method,
                                 data=json.dumps(body).encode() if body else None,
                                 headers={"Authorization": f"Bearer {KEY}", "Content-Type": "application/json",
                                          "User-Agent": "reviews-csv/1.0"})
    try:
        with urllib.request.urlopen(req, timeout=120) as r:
            return r.status, json.load(r)
    except urllib.error.HTTPError as e:
        return e.code, json.load(e)

def fetch_page(params):
    body = {"platform": "google_maps_reviews", "action": "reviews", "params": params}
    for attempt in range(4):
        status, data = call("POST", "/api/v1/social", body)
        err = (data.get("error") or {})
        if status == 429 or (err.get("retryable") and status >= 500):
            time.sleep(err.get("retry_after", 20)); continue
        if err.get("code") == "async_required":          # deep pages run as a job
            body["mode"] = "async"; continue
        if status == 202 and data.get("poll_url"):
            billing, poll = data.get("billing"), data["poll_url"]   # async jobs are charged at submit
            while data.get("status") in ("queued", "running", "finalizing"):
                time.sleep(5); status, data = call("GET", poll)
            data["billing"] = data.get("billing") or billing
            return data
        if err:
            raise SystemExit(f"stop: {err.get('code')} {err.get('message')}")
        return data
    raise SystemExit("stop: retries used up")

def main():
    url, out = sys.argv[1], sys.argv[2]
    max_pages = int(sys.argv[3]) if len(sys.argv) > 3 else 2
    params = {"url": url, "sort": "newest", "limit": 100}
    seen, rows, spent = set(), [], 0.0
    for page in range(max_pages):
        data = fetch_page(params)
        spent += (data.get("billing") or {}).get("charged_usd") or 0
        for r in data.get("results") or []:
            if r["id"] in seen:
                continue
            seen.add(r["id"])
            rows.append({k: r.get(k, "") for k in FIELDS})
        token = data.get("next_page_token")
        print(f"page {page + 1}: {data.get('count')} rows, total {len(rows)}")
        if not token or not (data.get("pagination") or {}).get("has_more"):
            break
        params["page_token"] = token
    rows.sort(key=lambda r: r["posted_at"] or "", reverse=True)   # "newest" is not strictly ordered
    with open(out, "w", newline="", encoding="utf-8-sig") as f:
        w = csv.DictWriter(f, fieldnames=FIELDS)
        w.writeheader(); w.writerows(rows)
    print(f"wrote {len(rows)} reviews to {out}; charged: ${spent:.6f}")

if __name__ == "__main__":
    main()

멕시코시티 타케리아를 대상으로 매번 세 페이지씩 세 번 실행했습니다. 첫 번째 실행은 00:32:39(SGT)에 시작했습니다. 1페이지와 2페이지는 정상이었고 3페이지는 비동기 작업으로 전환되었습니다. 그런데 폴링 응답에는 poll_url이 없는데 코드가 루프마다 이 값을 읽는 바람에 폴링 루프가 중단되었습니다. 두 번째 실행은 이 문제를 고친 뒤 00:33:18(SGT)에 시작했습니다. 이번에는 작업에 finalizing 상태가 있는데 코드가 이를 완료로 처리해 3페이지가 0행으로 돌아왔습니다.

세 번째 실행은 00:35:21(SGT)에 시작해 00:36:21(SGT)에 끝났습니다. 100개씩 세 페이지를 읽어 리뷰 300개를 저장했으며, ID도 300개 모두 고유했습니다. 과금액은 $0.004167이었습니다. CSV는 utf-8-sig를 사용하므로 Excel에서 열어도 글자가 깨지지 않습니다. 리뷰 텍스트 안의 줄바꿈은 셀 안에 유지되므로 300행 파일이 374줄인 것은 정상입니다. dialect 옵션은 Python csv 모듈 문서에 설명되어 있습니다 [38].

두 버그 모두 문서를 읽을 때는 보이지 않았지만 실제로 실행하자 바로 드러났습니다. 세 번의 실행 로그는 모두 보관했습니다. 새 비동기 API는 리뷰가 많은 장소로 테스트하세요. 3페이지까지 가서 상태 값을 하나하나 출력해 보세요.

내보낸 뒤: 정리 단계 다섯 가지

데이터를 가져오는 것은 절반일 뿐이고 나머지는 정리 작업입니다. 장소 3곳에서 받은 리뷰 700개의 문제는 다섯 가지 유형으로 나뉘었습니다. 유형마다 간단한 해결 방법이 있습니다. 결과 수치가 맞지 않는다고 드러난 뒤에 고치지 말고 첫 분석 스크립트부터 반영하세요.

첫 번째 유형은 시간입니다. posted_at과 owner_response_at은 시간대 접미사가 붙은 UTC 시각입니다. 오스틴은 겨울에 UTC−6, 여름에 UTC−5이므로 현지 시각 오후 9시에 올라온 리뷰는 UTC 기준으로 이미 다음 날입니다.

일별 리뷰 수를 집계한다면 먼저 장소의 현지 시각으로 변환하세요. 그러지 않으면 하루 경계가 몇 시간씩 밀려 주말 효과가 사라집니다. CSV에는 원본 UTC 문자열을 그대로 두고, 분석 단계에서 도시별로 변환합니다.

두 번째 유형은 빈 텍스트입니다. 세 장소의 최신 리뷰 중 35~45%는 텍스트가 없습니다. 감성 분석이나 키워드 분석에서는 빈 행을 제외하고 보고서에 분모를 밝히세요. 별점 추세 분석에서는 그대로 두세요. 같은 데이터로 두 관점을 모두 분석해 비교하세요. 앞의 오스틴 수치는 두 그룹이 얼마나 다를 수 있는지 보여 줍니다.

세 번째 유형은 세부 점수의 언어입니다. detailed_rating의 키는 리뷰 언어를 따릅니다. 멕시코시티에서 lang: es419를 쓰자 키가 comida, servicio, ambiente였습니다. 영어로 된 싱가포르 리뷰에서는 food, service, atmosphere였습니다.

여러 국가의 데이터를 한 테이블로 합친다면 먼저 키를 하나의 체계로 매핑하세요. 그러지 않으면 같은 "service" 점수가 두 열로 나뉩니다. 카탈로그 필드 목록에는 이 내용이 나오지 않습니다. 저희도 두 응답을 나란히 놓고 보다가 발견했습니다.

네 번째 유형은 중복입니다. 리뷰 하나가 두 페이지에 나타날 수 있으며, 몇 시간 뒤 다시 실행할 때 가장 자주 발생합니다. 새 리뷰가 기존 리뷰를 아래로 밀어내 페이지 경계가 겹치기 때문입니다. 내보내기 스크립트처럼 리뷰 id로 중복을 제거하세요. 장소는 검색마다 다른 이름으로 나타날 수 있으므로 장소 ID로 중복을 제거하세요. 리뷰 url은 hl=en 같은 언어 파라미터를 포함하므로 키로 쓰지 마세요.

다섯 번째 유형은 장소 필드입니다. 검색 결과의 state와 city 값은 정제된 코드가 아니라 표시용 텍스트입니다. 위치 파라미터를 쓴 멕시코시티 검색에서는 한 주가 두 가지 표기로 나타나기도 합니다. Zacatecas는 13행이 "Zacatecas", 1행이 "Zac."입니다. Quintana Roo는 2행이 "Quintana Roo", 2행이 "Q.R."입니다. Nuevo León, Jalisco, Tabasco에도 약칭이 있습니다.

멕시코시티 밖의 49행에는 주 문자열이 16종류 나오지만 실제 주는 11개뿐입니다. 키워드 검색에서는 state가 42행에서 "Cd. de México", 8행에서 "CDMX"입니다. 싱가포르 검색에서는 50행 중 2행에 city가 없습니다. 원본 state로 그룹화하면 한 주가 두 행으로 나뉩니다. 그룹화하기 전에 약칭을 정식 명칭으로 매핑하거나, 위도와 경도로 지역을 판별하세요.

문제확인한 내용해결 방법
시간대posted_at은 UTC일별로 집계하기 전에 현지 시각으로 변환
빈 텍스트최신 행의 35~45%텍스트 분석에서는 제외, 별점 추세에서는 유지
세부 점수 키영어는 food, 스페인어는 comida합치기 전에 키를 하나의 체계로 매핑
중복실행 간 페이지 경계가 겹침리뷰 id와 장소 ID로 중복 제거
장소 필드"Zac."와 "Zacatecas", "CDMX"와 "Cd. de México"그룹화하기 전에 약칭을 하나의 이름으로 매핑

사용 사례별 비용

단가는 실제 작업에 대입해 보면 판단하기 쉽습니다. 아래 수치는 테스트에서 확인한 단가와 Google 가격표의 단가를 사용했습니다. 서버, 인건비 등 기타 비용은 제외했습니다.

첫 번째 작업은 영업 리드 목록입니다. 오스틴의 모든 치과를 이름, 전화번호, 웹사이트, 평점, 리뷰 수와 함께 수집하며 리뷰 텍스트는 필요 없습니다. EveryInfra 검색은 호출당 50곳을 $0.001389에 반환합니다. 저희가 받은 두 페이지로 서로 다른 치과 100곳을 $0.002778에 확보했습니다. 치과 1,000곳 목록에는 약 20회 호출이 필요하며, 비용은 $0.028입니다.

키워드 하나로는 페이지를 넘겨도 최대 120행까지만 받을 수 있으므로 도시를 지역별로 나누거나 키워드를 바꿔 가며 검색하세요. 공식 Text Search Pro SKU는 매달 무료 호출 5,000건을 제공하고, 그 이후에는 1,000건당 $32입니다 [3][6]. 이 규모라면 무료 한도로 작업 전체를 처리할 수 있습니다. 차이는 공식 결과에 적용되는 캐시 및 표시 규칙입니다 [7].

두 번째 작업은 리뷰 모니터링입니다. 지점 50곳을 둔 체인이 매주 한 번 지점별 새 리뷰를 확인합니다. 자사 지점이라면 Business Profile API가 무료이고 가장 적합합니다 [12]. 가맹점이나 대행사가 관리하는 지점이거나 고객사를 위해 모니터링한다면 데이터 API가 필요합니다.

장소당 매주 1회씩 52주 동안 50곳을 호출하면 2,600회이며, 연간 약 $3.61입니다. 공식 Places API로는 이 작업을 할 수 없습니다. 최신 리뷰를 반환하지 않고, 상위 5개가 몇 달 동안 그대로일 수 있기 때문입니다.

세 번째 작업은 리서치입니다. 한 지역에 식당이 500곳 있고, 각 식당의 최신 리뷰 100개, 총 50,000개를 원한다고 가정합니다. 데이터 API로는 리뷰 호출 500회와 검색 호출 약 15회, 즉 약 $0.72가 듭니다. 공식 Places API로는 최대 2,500개(500곳 × 5개)만 받을 수 있으며, 그마저도 선별된 표본입니다.

싱가포르 테스트에서 이 표본은 최근 리뷰보다 평균 별점이 0.15점 높았고 텍스트는 7배 넘게 길었습니다. 이론적으로는 직접 만든 스크래퍼로도 이 작업을 할 수 있습니다. 하지만 오픈소스 이슈 기록을 보면 중간에 "리뷰 10개만" 문제에 부딪힐 수 있습니다 [33].

작업공식 Places APIEveryInfra 데이터 API
오스틴 치과 1,000곳, 목록만Text Search 무료 한도 내약 20회 호출, $0.028
지점 50곳, 매주 새 리뷰, 1년불가, 최신순 정렬 없음2,600회 호출, 약 $3.61
식당 500곳, 각 최신 리뷰 100개최대 2,500개, 선별된 리뷰약 515회 호출, 약 $0.72

Google Maps 스크래퍼 고르는 법: 확인할 6가지

가장 좋은 Google Maps 스크래퍼를 찾는 사람에게 필요한 것은 가장 유명한 도구가 아닙니다. 감당할 수 있는 비용으로 필요한 데이터를 안정적으로 돌려주는 도구입니다. 브랜드가 아니라 항목별로 확인 사항을 정리했습니다. 각 항목은 몇 센트짜리 소규모 시험 실행으로 확인할 수 있습니다.

확인 항목테스트 방법저희 측정값
장소당 리뷰 수와 날짜순 페이지 이동리뷰가 1,000개 넘는 장소를 골라 3페이지까지 이동공식 API 5개. EveryInfra는 정렬 순서당 400행
과금 단위와 실패 시 과금잘못된 파라미터 1건과 미래 날짜 since 1건 전송422와 429는 무료. 빈 결과와 실패한 호출은 환불
리뷰 1,000개당 실제 비용과금액 ÷ 반환된 행 수 × 1,000호출당 100개 기준 $0.01389
필드업체 답글, 세부 점수, 사진 포함 여부 확인owner_response, detailed_rating, image_urls
위치 정확도같은 도시를 두 가지 위치 지정 방식으로 검색멕시코시티: 위치 파라미터 사용 시 50개 중 1개, 키워드 사용 시 50개 중 50개
AI 도구에서 사용MCP 또는 함수 호출 도구 정의 제공 여부 확인지원, 원격 MCP 서버

구매자가 가장 많이 건너뛰는 것은 두 번째 행입니다. 결과 건당 과금하는 도구는 보통 빈 결과에 요금을 부과하지 않지만, 중간에 끝난 작업에 대한 규칙은 도구마다 다릅니다. 호출당 과금 API라면 빈 결과와 실패한 호출이 환불되는지 확인하세요. 몇 센트짜리 테스트 한 번이면 답을 알 수 있습니다.

세 번째 행도 비슷합니다. 정가를 그대로 믿지 마세요. 실제 과금액을 실제 행 수로 나누세요. 1,000건당 가격은 대부분 페이지가 꽉 찬다고 가정하지만, 대상 장소의 리뷰는 수십 개뿐일 수도 있습니다.

공식 API나 직접 만든 스크래퍼가 더 나은 경우

데이터 API가 항상 최선은 아닙니다. 세 가지 경우에는 다른 경로를 권합니다. 첫째, 매달 1,000곳 미만의 장소에서 장소당 대표 리뷰 5개만 필요하다면 공식 Places API 무료 한도로 충분합니다. 작성자 정보를 표시하기만 하면 앱에 리뷰를 합법적으로 보여 줄 수도 있습니다.

둘째, 자사 지점의 리뷰라면 Business Profile API를 사용하세요. 모든 리뷰를 반환하고, 답글을 달 수 있으며, 비용도 들지 않습니다. 어떤 서드파티도 이를 따라올 수 없습니다.

셋째, 한 도시의 업체 목록만 필요하다면 정부 공공 데이터부터 시작하세요. 싱가포르에는 허가받은 식품 접객업소 데이터 세트가 36,000행 넘게 있습니다 [28]. 싱가포르 식품청(SFA)은 2026년 11월 1일 업소 이력 페이지를 업데이트했습니다 [29]. 멕시코에는 DENUE 디렉터리가 있고 [30], 미국 인구조사국에는 County Business Patterns가 있습니다 [31]. 이 데이터 세트에는 평점이나 리뷰가 없습니다. 흔히 정부 데이터를 기본 테이블로 두고 관심 있는 장소의 최근 리뷰를 더하는 방식으로 조합합니다.

직접 만든 스크래퍼가 가치 있는 경우는 하나뿐입니다. 브라우저에서만 보이는 요소처럼 요구 사항이 매우 구체적이고, 팀이 장기 유지보수 프로젝트를 감수할 수 있는 경우입니다. 언제든 망가질 수 있고 서비스 약관을 위반할 수 있다는 점도 받아들여야 합니다. 목표가 비용 절감뿐이라면 이 가이드의 수치는 반대 결과를 보여 줍니다. 리뷰 100개당 $0.001389이므로, 엔지니어 한 명이 스크립트를 한 번 수정하는 데 드는 인건비가 1년 치 API 호출 비용보다 큽니다.

EveryInfra에도 한계가 있으며, 이번 테스트에서 확인했습니다. 정렬 순서 하나당 400행에서 멈춥니다. 리뷰가 8,226개인 장소라면 전체 이력을 가져올 수 없습니다. 최신 400개와 관련성 상위 400개를 받을 수 있지만 두 세트는 서로 겹칩니다.

200행 이후의 데이터를 가져오려면 비동기 모드와 폴링 루프가 필요합니다. 멕시코시티에서는 위치 파라미터를 썼을 때 결과 50개 중 1개만 도시 안에 있었고, 원인은 아직 모릅니다.

FAQ

Google Maps를 무료로 스크래핑할 수 있나요?

합법적인 무료 방법은 두 가지입니다. 공식 Places API는 리뷰가 포함된 Place Details 호출을 매달 1,000건 무료로 제공하며, 호출당 리뷰는 최대 5개입니다 [3][4]. 자사 지점이라면 Business Profile API로 모든 리뷰를 무료로 읽을 수 있습니다 [11]. 흔히 말하는 "무료 스크래퍼"는 대개 오픈소스 소프트웨어를 뜻합니다. 다운로드는 무료지만 서버, 프록시, 유지보수에는 비용이 듭니다.

Python으로 Google Maps 리뷰를 스크래핑하려면 어떻게 해야 하나요?

일반 HTTP 요청으로는 리뷰를 받을 수 없습니다. 테스트에서 리뷰 스니펫 20개 중 페이지에 있는 것이 하나도 없었으므로, 브라우저 자동화나 데이터 API가 필요합니다. 이 가이드에는 코드 샘플이 두 개 있습니다. 하나는 실행하지 않은 브라우저 자동화 스케치이고, 다른 하나는 데이터 API를 호출하는 완성된 내보내기 스크립트로 세 번 실행했습니다. Reddit r/learnpython에서도 같은 질문이 올라온 적이 있습니다 [41].

Google Maps 스크래핑은 합법인가요?

Google 약관은 콘텐츠의 대량 다운로드와 스크래핑을 금지합니다 [13][14]. hiQ v. LinkedIn 판결과 Meta가 데이터 수집 회사를 상대로 낸 소송의 판결 등 미국 판례는 공개 데이터 스크래핑에 유리했습니다. 하지만 이 판결들은 특정 법적 쟁점에 대한 답이며, 약관 위반에는 여전히 대가가 따를 수 있습니다 [21][22].

리뷰 작성자 데이터에는 CCPA, GDPR 같은 법률도 적용됩니다. 이 가이드는 법률 자문이 아닙니다.

Places API는 왜 리뷰를 5개만 반환하며, 최신 리뷰는 어떻게 받을 수 있나요?

5개는 설계상 한도입니다. 참조 문서에는 관련성 순으로 정렬된 리뷰를 최대 5개 반환하며 페이지 토큰은 없다고 나와 있습니다 [1]. 자사 지점이라면 Business Profile API에서 업데이트 시각 기준으로 정렬하세요 [12]. 다른 장소라면 데이터 API나 스크래퍼를 사용하세요. Stack Overflow 질문 39223719와 55235501의 답변도 같은 한도에서 멈춥니다 [39][40].

가장 좋은 Google Maps 스크래퍼는 무엇인가요?

정답은 하나가 아닙니다. 필요한 리뷰 수, 날짜순 페이지 이동이 필요한지, 어떤 과금 모델을 받아들일 수 있는지에 따라 달라집니다. 이 가이드에서는 몇 센트로 테스트할 수 있는 확인 항목 6가지를 제시합니다. 장소당 리뷰 수, 실패 시 과금, 리뷰 1,000개당 실제 비용, 필드, 위치 정확도, AI 도구에서의 사용입니다.

Google Maps 리뷰 스크래핑 비용은 얼마인가요?

EveryInfra에서는 호출 1건으로 리뷰를 최대 100개 받고 $0.001389가 과금되므로, 리뷰 1,000개의 비용은 약 $0.01389입니다. 이 가이드의 모든 테스트에는 요청 36건과 과금된 호출 26건이 사용되었으며, 총비용은 $0.036113이었습니다. 공식 Places API에서는 무료 한도를 넘으면 리뷰 1,000개의 비용이 약 $5.00입니다.

시작하기

빠른 시작에서 계정과 API 키를 만드세요. 새 계정에는 체험용 크레딧이 제공되며, 현재 조건은 요금 페이지에서 확인할 수 있습니다. 무료 카탈로그 GET /api/v1/social/catalog에서 google_maps_reviews의 파라미터와 가격을 확인하세요. 이 가이드의 curl 요청을 잘 아는 장소에 보내 보세요. 필요한 필드가 있는지 확인하세요. CSV 내보내기 스크립트를 저장하고, 두 페이지로 실행해 본 다음 필요에 따라 페이지를 늘리세요.

리뷰 플랫폼을 비교하려면 Yelp 데이터 API와 Tripadvisor 데이터 API를 참고하세요. 전체 구축 과정은 Google Maps 리뷰 API 튜토리얼에서 확인하세요.

방법과 한계

EveryInfra 호출은 모두 2026년 11월 2일 00:14~00:36(SGT)에 실행했습니다. 테스트 키의 한도는 분당 요청 10건이었습니다. 세 도시에서 장소를 하나씩만 골랐으므로, 샘플은 해당 시점의 해당 장소 리뷰이며 모든 업체의 리뷰가 아닙니다. 관련도순과 최신순 결과는 시간에 따라 달라집니다.

Places API 요금과 한도는 2026년 11월 2일 기준 Google 페이지에서 가져왔습니다. API 키로 Places API를 호출하지는 않았습니다. 브라우저 자동화 코드도 실행하지 않았습니다. Maps 페이지에는 일반 HTTP 요청을 한 번만 보냈습니다.

“리뷰 1,000건당” 가격은 다음과 같이 계산했습니다. EveryInfra 쪽은 각 응답의 charged_usd를 해당 응답의 리뷰 수로 나눈 뒤 1,000을 곱했습니다. 리뷰 페이지 9개 모두 리뷰가 100건이었으므로 모두 $0.01389가 나왔습니다. 과금이 호출 단위이므로 리뷰가 100건 미만인 장소나 더 작은 limit에서는 리뷰당 가격이 더 높아집니다.

Places API 쪽은 호출당 리뷰 5건을 가정하고 티어 가격을 5로 나눴습니다. 양쪽 모두 무료 한도와 체험용 크레딧은 반영하지 않았습니다. 월별 리뷰 수에 설명할 수 없는 변동이 있어 추세 차트는 그리지 않았습니다.

아래 표에 이 가이드에서 과금된 모든 호출을 정리했습니다. 시각은 모두 2026년 11월 2일 SGT 기준입니다.

시각(SGT)기능대상반환 건수과금
00:14:43google_maps_reviews/search싱가포르, 바쿠테장소 50곳$0.001389
00:15:07google_maps_reviews/profileSong Fa Bak Kut Teh장소 1곳$0.001389
00:15:29, 00:16:42google_maps_reviews/reviewsSong Fa, 최신순 1·2페이지각 100건건당 $0.001389
00:16:10google_maps_reviews/reviewsSong Fa, 관련도순100$0.001389
00:18:27google_maps_reviews/reviews 비동기Song Fa, 최신순 3페이지100$0.001389
00:17:10, 00:24:22google_maps_reviews/search오스틴 치과, 페이지 2개각 50건건당 $0.001389
00:20:02google_maps_reviews/profileSwish Dental장소 1곳$0.001389
00:20:36, 00:23:41google_maps_reviews/reviewsSwish Dental, 페이지 2개각 100건건당 $0.001389
00:17:32, 00:19:39google_maps_reviews/search멕시코시티, 위치 지정 방식 2가지각 50건건당 $0.001389
00:22:35google_maps_reviews/profileTacos Chupacabras장소 1곳$0.001389
00:23:05, 00:23:24, 00:34:37google_maps_reviews/reviewsChupacabras, 페이지 3개각 100건건당 $0.001389
00:32:39~00:36:21google_maps_reviews/reviewsCSV 내보내기 3회 실행과금된 호출 9건$0.012501

합계는 과금된 호출 26건, $0.036113입니다. 이 밖에 호출 2건(빈 결과 1건, 실패 1건)은 환불되었고, 파라미터 오류와 요청 속도 제한 오류 5건은 비용이 발생하지 않았습니다.

참고 자료

  1. Google Maps Platform, “Places API (New) REST reference, Place resource”. https://developers.google.com/maps/documentation/places/web-service/reference/rest/v1/places
  2. Google Maps Platform, “Place Details (New)”. https://developers.google.com/maps/documentation/places/web-service/place-details
  3. Google Maps Platform, “core services pricing list”. https://developers.google.com/maps/billing-and-pricing/pricing
  4. Google Maps Platform, “billing and pricing overview”, 2026-10-30 업데이트. https://developers.google.com/maps/billing-and-pricing/overview
  5. Google Maps Platform, “Places API usage and billing”. https://developers.google.com/maps/documentation/places/web-service/usage-and-billing
  6. Google Maps Platform, “Text Search (New)”. https://developers.google.com/maps/documentation/places/web-service/text-search
  7. Google Maps Platform, “Places API policies”. https://developers.google.com/maps/documentation/places/web-service/policies
  8. Google Maps Platform, “Place IDs”. https://developers.google.com/maps/documentation/places/web-service/place-id
  9. Google Maps Platform, “review summaries”. https://developers.google.com/maps/documentation/places/web-service/review-summaries
  10. Google Maps Platform, “Places API release notes”. https://developers.google.com/maps/documentation/places/web-service/release-notes
  11. Google Business Profile APIs, “work with review data”. https://developers.google.com/my-business/content/review-data
  12. Google Business Profile APIs, “accounts.locations.reviews.list”. https://developers.google.com/my-business/reference/rest/v4/accounts.locations.reviews/list
  13. “Google Maps Platform Terms of Service”, 3.2.3(a)항. https://cloud.google.com/maps-platform/terms
  14. “Google Maps and Google Earth Additional Terms of Service”. https://www.google.com/help/terms_maps/
  15. “Google Maps user contributed content policy”, 금지 콘텐츠 항목. https://support.google.com/contributionpolicy/answer/7400114
  16. google.com robots.txt, 2026-11-02 다운로드. https://www.google.com/robots.txt
  17. IETF, “RFC 9309 Robots Exclusion Protocol”. https://www.rfc-editor.org/rfc/rfc9309.html
  18. Google 블로그, “Fan-Favorite Dining List”, 2026년 10월 8일. https://blog.google/products-and-platforms/products/maps/google-maps-fan-favorite-dining-list/
  19. 9to5Google, “Gemini in Google Maps on CarPlay”, 2026년 10월 21일. https://9to5google.com/2026/10/21/google-maps-carplay-gemini/
  20. Search Engine Land, “Google Ask Maps and local businesses”. https://searchengineland.com/google-ask-maps-make-your-business-easier-to-recommend-496672
  21. 미국 제9순회항소법원, hiQ Labs v. LinkedIn, 2022년 4월 18일. https://cdn.ca9.uscourts.gov/datastore/opinions/2022/04/18/17-16783.pdf
  22. 미국 캘리포니아 북부지방법원, Meta Platforms 사건 3:23-cv-00077, 2024년 1월 23일 명령. https://www.govinfo.gov/app/details/USCOURTS-cand-3_23-cv-00077/USCOURTS-cand-3_23-cv-00077-7
  23. 캘리포니아주 법무장관실, “California Consumer Privacy Act”. https://oag.ca.gov/privacy/ccpa
  24. 유럽연합, “Regulation (EU) 2016/679 (GDPR)”. https://eur-lex.europa.eu/eli/reg/2016/679/oj
  25. 싱가포르 PDPC, “PDPA overview”. https://www.pdpc.gov.sg/about/the-legislation/pdpa-overview
  26. 싱가포르 PDPC, “Personal Data Protection Act”. https://www.pdpc.gov.sg/overview-of-pdpa/the-legislation/personal-data-protection-act
  27. 멕시코, 민간 보유 개인정보 보호에 관한 연방법, DOF 2025-03-20. https://www.ordenjuridico.gob.mx/Documentos/Federal/html/wo125102.html
  28. data.gov.sg, “NEA licensed eating establishments”. https://data.gov.sg/datasets/d_227473e811b09731e64725f140b77697/view
  29. Singapore Food Agency, “track records”, 2026년 11월 1일 업데이트. https://www.sfa.gov.sg/tools-and-resources/track-records
  30. INEGI, DENUE 전국 사업체 명부. https://www.inegi.org.mx/app/mapa/denue/default.aspx
  31. 미국 인구조사국, “County Business Patterns”. https://www.census.gov/programs-surveys/cbp.html
  32. GitHub, 오픈소스 Google Maps 스크래퍼 프로젝트, 스타 7,148개. https://github.com/gosom/google-maps-scraper
  33. GitHub 이슈 327, 2026년 9월 1일. https://github.com/gosom/google-maps-scraper/issues/327
  34. GitHub 이슈 338, 2026년 10월 6일. https://github.com/gosom/google-maps-scraper/issues/338
  35. GitHub 이슈 341, 2026년 10월 9일. https://github.com/gosom/google-maps-scraper/issues/341
  36. GitHub 릴리스, v1.16.3~v1.18.1. https://github.com/gosom/google-maps-scraper/releases
  37. Playwright for Python, “installation”. https://playwright.dev/python/docs/intro
  38. Python 문서, csv 모듈. https://docs.python.org/3/library/csv.html
  39. Stack Overflow, Places API에서 리뷰 5개 넘게 가져오기. https://stackoverflow.com/questions/39223719/to-get-more-than-5-reviews-from-google-places-api
  40. Stack Overflow, Places API로 최신 리뷰 가져오기. https://stackoverflow.com/questions/55235501/how-to-get-latest-reviews-using-google-places-api
  41. Reddit r/learnpython, 장소 리뷰를 가져오는 방법. https://www.reddit.com/r/learnpython/comments/1c94ejb/how_can_i_get_places_reviews/
  42. GitHub 이슈 337, 2026년 10월 5일. https://github.com/gosom/google-maps-scraper/issues/337
  43. GitHub 이슈 346, 2026년 10월 22일. https://github.com/gosom/google-maps-scraper/issues/346

참고 BL-70