خانه/مقالات/استخراج داده از گوگل مپ با پایتون
استخراج داده از گوگل مپ با پایتون

استخراج داده از گوگل مپ با پایتون

در این مقاله، با مفهوم Web Scraping آشنا می‌شویم و یاد می‌گیریم چگونه با استفاده از زبان پایتون و ابزار Selenium، داده‌های Google Maps را به‌صورت مرحله‌به‌مرحله استخراج و در قالب فایل‌های قابل‌استفاده ذخیره کنیم. تمرکز این آموزش بر پیاده‌سازی عملی و درک منطق فنی فرآیند استخراج داده است.
Yazdan Shabab
Yazdan Shabab
1404-11-28

گوگل مپ یکی از بزرگ‌ترین منابع اطلاعات مکانی و تجاری در اینترنت است. میلیون‌ها کسب‌وکار در سراسر جهان اطلاعات خود را شامل نام، آدرس، شماره تماس، وب‌سایت، ساعت کاری، امتیاز کاربران و نظرات در Google Maps ثبت کرده‌اند. استخراج خودکار این داده‌ها می‌تواند برای تحلیل بازار، بررسی رقبا، تحقیقات محلی و پروژه‌های داده‌محور بسیار ارزشمند باشد.

در این مقاله، به‌صورت گام‌به‌گام یاد می‌گیریم چگونه با استفاده از زبان پایتون و ابزارهای اتوماسیون مرورگر، داده‌ها را از Google Maps استخراج کنیم. تمرکز این آموزش روی درک منطق اسکریپت، ساختار صفحه و پیاده‌سازی عملی است.

Web Scraping چیست؟

Web Scraping یا استخراج داده از وب، فرآیندی است که در آن اطلاعات موجود در صفحات وب به‌صورت خودکار جمع‌آوری می‌شوند. به‌جای کپی دستی داده‌ها، اسکریپت‌ها و برنامه‌ها این کار را انجام می‌دهند و خروجی ساخت‌یافته‌ای مثل CSV یا JSON تولید می‌کنند.

وقتی صحبت از Google Maps می‌شود، به دلیل پویابودن صفحه و بارگذاری تدریجی داده‌ها، نمی‌توان از روش‌های ساده HTML Scraping استفاده کرد و نیاز به شبیه‌سازی رفتار کاربر واقعی داریم.

چه داده‌هایی را می‌توان از گوگل مپ استخراج کرد؟

  • نام کسب‌وکار
  • آدرس فیزیکی
  • شماره تلفن
  • وب‌سایت
  • ساعت کاری
  • امتیاز (Stars)
  • تعداد نظرات
  • تصاویر

چرا برای Google Maps از Selenium استفاده می‌کنیم؟

Google Maps یک وب‌سایت کاملاً داینامیک است. داده‌ها با JavaScript بارگذاری می‌شوند و ساخت URL جستجو نیز پیچیده است. به همین دلیل بهترین راهکار استفاده از ابزارهای Browser Automation مانند Selenium است.

Selenium امکان کنترل مرورگر واقعی را فراهم می‌کند و می‌تواند رفتار کاربر انسانی مثل تایپ، کلیک و اسکرول را شبیه‌سازی کند.

مرحله ۱: آماده‌سازی پروژه

ابتدا مطمئن شوید Python 3 روی سیستم شما نصب شده است. سپس یک پوشه برای پروژه ایجاد کرده و محیط مجازی بسازید.

mkdir google-maps-scraper
cd google-maps-scraper
python -m venv env

پس از فعال‌سازی محیط مجازی:

env/Scripts/activate

مرحله ۲: نصب کتابخانه‌ها

برای این پروژه از Selenium استفاده می‌کنیم. آن را با دستور زیر نصب کنید:

pip install selenium

مرحله ۳: راه‌اندازی WebDriver

در فایل scraper.py ابتدا WebDriver کروم را در حالت Headless راه‌اندازی می‌کنیم.

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless")
driver = webdriver.Chrome(
    service=Service(),
    options=options
)

مرحله ۴: اتصال به Google Maps

 

در این مرحله مرورگر کنترل‌شده را به صفحه اصلی Google Maps هدایت می‌کنیم.

driver.get("https://www.google.com/maps")

مرحله ۵: مدیریت پنجره GDPR (در صورت نیاز)

در برخی کشورها، گوگل پنجره پذیرش کوکی‌ها را نمایش می‌دهد. برای جلوگیری از توقف اسکریپت، این مرحله را مدیریت می‌کنیم.

from selenium.webdriver.common.by import By
from selenium.common import NoSuchElementException
try:
    accept_button = driver.find_element(By.CSS_SELECTOR, '[aria-label="Accept all"]')
    accept_button.click()
except NoSuchElementException:
    pass

مرحله ۶: جستجو در گوگل مپ

اکنون باید عبارت موردنظر خود را در کادر جستجو وارد کنیم.

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
search_input = WebDriverWait(driver, 5).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "#searchboxinput"))
)
search_input.send_keys("italian restaurants")
search_button = driver.find_element(By.CSS_SELECTOR, 'button[aria-label="Search"]')
search_button.click()

مرحله ۷: انتخاب آیتم‌های نتایج

نتایج جستجو در ستون سمت چپ نمایش داده می‌شوند. این بخش به‌صورت پویا بارگذاری می‌شود و باید منتظر آن بمانیم.

items = []
maps_items = WebDriverWait(driver, 10).until(
    EC.presence_of_all_elements_located(
        (By.XPATH, '//div[@role="feed"]//div[contains(@jsaction,"mouseover:pane")]')
    )
)

مرحله ۸: استخراج اطلاعات هر آیتم

در این مرحله اطلاعات اصلی هر کسب‌وکار استخراج می‌شود.

import re
for maps_item in maps_items:
    title = maps_item.find_element(
        By.CSS_SELECTOR, "div.fontHeadlineSmall"
    ).text
    link = maps_item.find_element(
        By.CSS_SELECTOR, "a[jsaction][jslog]"
    ).get_attribute("href")
    items.append({
        "title": title,
        "url": link
    })

مرحله ۹: ذخیره داده‌ها در CSV

در نهایت داده‌ها را در یک فایل CSV ذخیره می‌کنیم.

import csv
with open("items.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["title", "url"])
    writer.writeheader()
    for item in items:
        writer.writerow(item)

محدودیت‌ها و نکات مهم

  • Google Maps مکانیزم‌های ضد ربات دارد
  • اجرای زیاد اسکریپت ممکن است باعث مسدود شدن IP شود
  • برای پروژه‌های بزرگ نیاز به مدیریت خطا و کپچا است

افزودن سیستم لاگ (Logging) برای مانیتور کردن اسکریپت

در پروژه‌های واقعی، اجرای اسکریپت بدون لاگ‌گیری یک ریسک بزرگ است. اگر اسکریپت در میانه اجرا متوقف شود یا گوگل مپ ساختار صفحه را تغییر دهد، بدون لاگ تقریباً غیرممکن است بفهمید مشکل از کجاست.

با استفاده از ماژول logging در پایتون می‌توان وضعیت اجرای اسکریپت، خطاها و مراحل مهم را ثبت کرد.

import logging
logging.basicConfig(
    filename="scraper.log",
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)
logging.info("Script started")

از این لاگ‌ها می‌توانید برای دیباگ، مانیتورینگ و حتی تحلیل عملکرد اسکریپت استفاده کنید.

مدیریت خطا با Retry هوشمند

یکی از مشکلات رایج در Google Maps Scraping، خطاهای موقتی مانند Timeout یا لود نشدن المان‌هاست. به‌جای توقف کامل اسکریپت، بهتر است مکانیزم Retry اضافه شود.

from selenium.common.exceptions import TimeoutException
import time
def safe_find(driver, by, value, retries=3):
    for i in range(retries):
        try:
            return driver.find_element(by, value)
        except TimeoutException:
            time.sleep(2)
    return None

این روش باعث می‌شود اسکریپت شما پایدارتر شود و در شرایط ناپایدار اینترنت به‌طور کامل از کار نیفتد.

تشخیص خودکار تغییر ساختار صفحه

یکی از مشکلات جدی اسکریپ‌های Selenium این است که با کوچک‌ترین تغییر در ساختار HTML، کل پروژه از کار می‌افتد. برای کاهش این ریسک، می‌توان بررسی وجود المان‌ها را شرطی کرد.

if driver.find_elements(By.CSS_SELECTOR, "div.fontHeadlineSmall"):
    logging.info("Layout looks normal")
else:
    logging.warning("Page layout may have changed")

با این کار، در صورت تغییر ساختار صفحه، می‌توانید سریعاً متوجه مشکل شوید و اسکریپت را به‌روزرسانی کنید.

ذخیره داده‌ها در پایگاه داده به‌جای CSV

برای پروژه‌های بزرگ، ذخیره اطلاعات در CSV کافی نیست. استفاده از دیتابیس امکان جستجو، فیلتر و تحلیل داده‌ها را بسیار ساده‌تر می‌کند.

مثال ساده با SQLite:

import sqlite3
conn = sqlite3.connect("maps_data.db")
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS places (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT,
    address TEXT,
    phone TEXT
)
""")
conn.commit()

این کار پروژه شما را یک قدم به سمت سیستم‌های داده‌محور واقعی نزدیک می‌کند.

افزودن پشتیبانی از چند شهر یا چند کوئری

به‌جای اجرای اسکریپت فقط برای یک عبارت جستجو، می‌توانید لیستی از شهرها یا دسته‌بندی‌ها تعریف کنید.

queries = [
    "coffee shop in Tehran",
    "coffee shop in Shiraz",
    "coffee shop in Isfahan"
]
for query in queries:
    search_input.clear()
    search_input.send_keys(query)
    search_button.click()

این قابلیت پروژه شما را از یک اسکریپت ساده به یک ابزار جمع‌آوری داده چندمنظوره تبدیل می‌کند.

برچسب‌گذاری و غنی‌سازی داده‌ها

یکی از ایده‌های حرفه‌ای، افزودن متادیتا به داده‌های استخراج‌شده است. برای مثال می‌توانید مشخص کنید هر داده مربوط به کدام شهر، کدام دسته‌بندی یا کدام تاریخ استخراج است.

item = {
    "title": title,
    "city": "Tehran",
    "category": "Coffee Shop",
    "scraped_at": datetime.now().isoformat()
}

این کار در تحلیل‌های بعدی و داشبوردهای داده بسیار ارزشمند خواهد بود.

چرا اینجا API انتخاب منطقی‌تری می‌شود؟

با اضافه شدن این قابلیت‌ها، نگهداری اسکریپت Selenium به‌مرور پیچیده‌تر و پرهزینه‌تر می‌شود. در چنین شرایطی استفاده از API آماده، هم از نظر زمان توسعه و هم از نظر پایداری، تصمیم هوشمندانه‌تری است.

سرویس AsanScrape این امکان را فراهم می‌کند که تمام این مراحل (مدیریت خطا، کپچا، تغییر ساختار صفحه و مقیاس‌پذیری) در لایه API انجام شود و شما فقط داده نهایی را دریافت کنید.

روش‌هایی که در این مقاله بررسی کردیم، یک مسیر کاملاً عملی برای استخراج داده از :contentReference[oaicite:0]{index=0} با استفاده از پایتون و Selenium هستند. این روش‌ها برای یادگیری وب‌اسکریپینگ، پروژه‌های تحقیقاتی، تست ایده‌ها و استخراج داده در مقیاس محدود بسیار مناسب‌اند.

اما در سناریوهای واقعی و پروژه‌های بزرگ‌تر، چالش‌هایی مانند مدیریت کپچا، تغییر ساختار DOM صفحات، محدودیت نرخ درخواست‌ها (Rate Limit) و مسدود شدن IP می‌توانند باعث شوند اسکریپت‌های ساده به‌سرعت ناکارآمد شوند.

افزایش پایداری اسکریپت Selenium

 

برای کاهش ریسک شناسایی ربات، می‌توان تنظیمات مرورگر را به‌گونه‌ای انجام داد که رفتار آن به کاربر واقعی نزدیک‌تر باشد. برای مثال:

from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("--lang=en-US")
options.add_argument("--window-size=1920,1080")
options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64)")

این تنظیمات باعث می‌شوند Selenium کمتر شبیه یک ربات رفتار کند و احتمال بلاک شدن کاهش یابد. با این حال، حتی با این روش‌ها نیز گوگل مپ در استفاده طولانی‌مدت محدودیت‌هایی اعمال می‌کند.

اسکرول خودکار برای بارگذاری نتایج بیشتر

از آنجا که نتایج Google Maps به‌صورت Lazy Load بارگذاری می‌شوند، باید اسکرول ستون نتایج را شبیه‌سازی کنیم:

import time
scrollable_div = driver.find_element(By.XPATH, '//div[@role="feed"]')
for i in range(5):
    driver.execute_script(
        "arguments[0].scrollTop = arguments[0].scrollHeight",
        scrollable_div
    )
    time.sleep(3)

با این کار، نتایج بیشتری بارگذاری می‌شوند و می‌توان داده‌های بیشتری از کسب‌وکارها استخراج کرد.

استخراج اطلاعات تکمیلی هر کسب‌وکار

پس از کلیک روی هر آیتم، صفحه جزئیات باز می‌شود و می‌توان اطلاعات کامل‌تری مانند شماره تماس، آدرس دقیق و ساعت کاری را استخراج کرد:

address = driver.find_element(
    By.XPATH, '//button[@data-item-id="address"]'
).text
phone = driver.find_element(
    By.XPATH, '//button[contains(@data-item-id,"phone")]'
).text

این مرحله معمولاً حساس‌ترین بخش اسکریپت است، زیرا ساختار HTML در مناطق مختلف یا نسخه‌های مختلف Google Maps تغییر می‌کند.

چرا برای پروژه‌های بزرگ این روش کافی نیست؟

اگر بخواهید هزاران یا میلیون‌ها رکورد از Google Maps استخراج کنید، مدیریت مواردی مانند:

  • چرخش IP و پروکسی
  • حل کپچا به‌صورت خودکار
  • مانیتورینگ خطاها و ریتری (Retry)
  • تغییر مداوم Selectors

به یک چالش جدی تبدیل می‌شود و هزینه نگهداری اسکریپت‌ها به‌مرور افزایش می‌یابد. در این نقطه، استفاده از یک راهکار حرفه‌ای منطقی‌تر است.

 

چالش‌ها و محدودیت‌های این روش در دنیای واقعی

روش‌هایی که در این مقاله بررسی کردیم، از نظر آموزشی و پیاده‌سازی فنی بسیار مفید هستند و برای پروژه‌های کوچک، تست ایده‌ها و یادگیری وب اسکریپینگ انتخاب مناسبی محسوب می‌شوند. اما در دنیای واقعی و به‌خصوص در پروژه‌های بزرگ‌تر، این فرآیند با محدودیت‌ها و چالش‌های متعددی همراه است.

Google Maps به‌صورت فعال از مکانیزم‌های ضد ربات استفاده می‌کند و اجرای مداوم اسکریپت‌های Selenium می‌تواند منجر به مسدود شدن IP، نمایش کپچا، کاهش سرعت پاسخ‌دهی و حتی از کار افتادن کامل اسکریپت شود. علاوه بر این، تغییر مداوم ساختار صفحات باعث می‌شود نیاز به نگهداری و به‌روزرسانی دائمی کدها وجود داشته باشد.

مدیریت مواردی مانند چرخش IP، حل کپچا، کنترل خطاها، مانیتورینگ اجرا و مقیاس‌پذیری، در نهایت زمان و هزینه توسعه پروژه را به‌شدت افزایش می‌دهد و تمرکز تیم را از تحلیل داده‌ها دور می‌کند.

به همین دلیل، در بسیاری از پروژه‌های حرفه‌ای و تجاری، به‌جای پیاده‌سازی و نگهداری اسکریپت‌های پیچیده، استفاده از سرویس‌های آماده و تخصصی استخراج داده انتخاب منطقی‌تر و مقرون‌به‌صرفه‌تری محسوب می‌شود.

راه‌حل حرفه‌ای‌تر: استفاده از API آماده (AsanScrape)

اگر می‌خواهید استخراج داده از Google Maps را پایدار، سریع و بدون دردسرهای Selenium انجام دهید، بهترین راه این است که به‌جای جنگیدن با کپچا، محدودیت‌ها و تغییرات رابط گوگل، از یک API تخصصی استفاده کنید. با AsanScrape می‌توانید خروجی ساخت‌یافته بگیرید و تمرکزتان را روی تحلیل داده و کاربردهای کسب‌وکاری بگذارید—برای شروع، از اسکرپر نقشه گوگل استفاده کنید.

با استفاده از API اختصاصی AsanScrape می‌توانید:

  • داده‌ها را به‌صورت ساخت‌یافته و قابل‌پردازش دریافت کنید
  • بدون نگرانی از کپچا، بلاک شدن IP و تغییرات مداوم گوگل کار کنید
  • در مقیاس بالا و با سرعت مناسب استخراج انجام دهید
  • صفحه‌بندی (Pagination) را با توکن ادامه دهید و نتایج بیشتری بگیرید

 

نمونه استفاده از API (پایتون)

import requests
BASE_URL = "https://backend.asanscrape.com"
API_KEY = ""
url = f"{BASE_URL}/robots/create/task/wait-for-result/"
headers = {
    "accept": "*/*",
    "Authorization": f"token {API_KEY}",
    "Content-Type": "application/json",
}
payload = {
    "robot": "google map advanced",
    "inputs": {
        "location": {
            "latitude": 35.738314,
            "longitude": 51.3338035,
            "zoom": 13,
        },
        "keyword": "کافه",
        "lang": "fa",
        "country": "ir",
    },
    "pagination_token": "NEXT_TOKEN (optional)",
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
data = response.json()
print(data)

در این مثال، با مشخص کردن موقعیت جغرافیایی (latitude/longitude/zoom) و یک کلیدواژه مثل «کافه»، ربات «google map advanced» نتایج را استخراج می‌کند. اگر داده‌ها چند صفحه باشند، می‌توانید با مقدار pagination_token صفحه بعدی را هم دریافت کنید.

این روش برای تیم‌های مارکتینگ، تحلیل بازار، تولید لید، و پروژه‌های داده‌محور که نیاز به خروجی قابل اتکا دارند، انتخابی حرفه‌ای و مقرون‌به‌صرفه است.

برای مشاهده مستندات کامل API و آشنایی با تمام قابلیت‌ها، می‌توانید اینجا را ببینید.

مقاله‌های مرتبط