• 18-03-2026, 23:09:55
    #1
    🛠️ Google Maps'ten İşletme Verisi Çeken Ücretsiz Python Scripti
    Firma adı · Telefon · Adres · Web sitesi · Puan · Fotoğraf → Excel & CSV

    📌 Bu Script Ne Yapıyor?

    Google Maps'te istediğiniz şehirde istediğiniz aramayı yapıp çıkan tüm işletmelerin;
    • Firma adı
    • Telefon numarası (05xxxxxxxxx formatında)
    • Adres
    • Web sitesi
    • Google puanı ve yorum sayısı
    • Çalışma saatleri
    • Öne çıkan fotoğraf URL'si
    • Google Maps linki
    bilgilerini otomatik olarak Excel (.xlsx) ve CSV dosyasına kaydeder.

    📋 KURULUM REHBERİ (Adım Adım)

    ADIM 1 — Python'u Kurun
    1. python.org/downloads adresine gidin
    2. Büyük sarı "Download Python 3.x" butonuna tıklayın
    3. İndirilen .exe dosyasını çalıştırın
    4. ÖNEMLİ: Kurulum ekranında "Add Python to PATH" kutucuğunu işaretleyin!
    ADIM 2 — Klasör Oluşturun

    C: sürücüsünde googlemap klasörü oluşturun → C:googlemap
    Ekteki google_maps_scraper.py dosyasını bu klasöre koyun.

    ADIM 3 — CMD'yi Açın
    1. Dosya Gezgini'nde C:googlemap klasörüne girin
    2. Üstteki adres çubuğuna tıklayıp içini silin
    3. cmd yazıp Enter'a basın
    ADIM 4 — Kütüphaneleri Kurun (Sadece 1 kez)

    CMD'ye sırasıyla yapıştırın:

    pip install playwright openpyxl
    Bitmesini bekleyin, sonra:
    python -m playwright install chromium
    ⏳ Bu komut ~150 MB indirir, 1-3 dakika sürebilir.

    ADIM 5 — Ayarları Yapın

    google_maps_scraper.py dosyasına sağ tıklayın → "Not Defteri ile Aç"
    Dosyanın en üstündeki bu satırları düzenleyin:

    ARAMA_TERIMI = "Beyaz esya tamircileri"   # ← İstediğiniz aramayı yazın
    SEHIR        = "Ankara"                    # ← İstediğiniz şehri yazın
    MAX_ISLETME  = 50                          # ← Kaç işletme çeksin?
    Değiştirdikten sonra Ctrl+S ile kaydedin.

    ADIM 6 — Çalıştırın

    python google_maps_scraper.py
    Otomatik bir tarayıcı açılır ve Google Maps'te arama yapılır. Siz sadece izleyin!
    Bitince C:googlemap klasöründe isletmeler.xlsx ve isletmeler.csv oluşur.

    ❓ Sık Sorulan Sorular

    Script hiçbir şey yazmadan kapandı?
    CMD'de şunu deneyin:
    python google_maps_scraper.py 2>&1 | more
    Farklı şehir veya sektör?
    AYARLAR bölümünden ARAMA_TERIMI ve SEHIR'i değiştirin, hepsi bu!

    Kaç işletmeye kadar çeker?
    Google Maps ~120 sonuç gösterir. MAX_ISLETME'yi 120'ye kadar artırabilirsiniz.

    Ücretli bir şey var mı?
    Hayır! Tamamen ücretsiz, API key gerektirmez.

    """
    Google Maps Isletme Veri Toplayici v5
    """
    
    import sys
    import csv
    import asyncio
    import traceback
    import re
    
    if sys.platform == "win32":
        asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
    
    # ============================================================
    #  AYARLAR
    # ============================================================
    ARAMA_TERIMI = "Beyaz Eşya Tamirhanesi"
    SEHIR        = "Ankara"
    MAX_ISLETME  = 10
    CIKTI_DOSYA  = "isletmeler"
    # ============================================================
    
    async def gorsel_url_al(page):
        selectors = [
            'button.aoRNLd img', 'div.RZ66Rb img',
            'img.t0ejtc', 'div.ZKCDEc img', 'div.brR1M img',
        ]
        for sel in selectors:
            try:
                el = await page.query_selector(sel)
                if el:
                    src = await el.get_attribute("src")
                    if src and src.startswith("http") and "googleusercontent" in src:
                        src = re.sub(r'=w\d+-h\d+', '=w800-h600', src)
                        src = re.sub(r'=s\d+', '=s800', src)
                        return src
            except:
                pass
        try:
            imgs = await page.query_selector_all('img[src*="googleusercontent"]')
            for img in imgs:
                src = await img.get_attribute("src")
                if src:
                    src = re.sub(r'=w\d+-h\d+', '=w800-h600', src)
                    return src
        except:
            pass
        return ""
    
    
    async def detay_cek(page):
        veri = {}
    
        # Firma Adı
        for sel in ['h1.DUwDvf', 'h1.fontHeadlineLarge', 'h1']:
            try:
                ad = (await page.inner_text(sel, timeout=2000)).strip()
                if ad:
                    veri["Firma Adi"] = ad
                    break
            except:
                pass
        veri.setdefault("Firma Adi", "")
    
        # Kategori
        for sel in ['button.DkEaL', 'span.YkuOqf']:
            try:
                kat = (await page.inner_text(sel, timeout=1500)).strip()
                if kat:
                    veri["Kategori"] = kat
                    break
            except:
                pass
        veri.setdefault("Kategori", "")
    
        # Puan
        try:
            el = await page.query_selector('span.ceNzKf[aria-label]')
            lbl = await el.get_attribute("aria-label") if el else ""
            m = re.search(r"[\d,\.]+", lbl or "")
            veri["Puan"] = m.group().replace(",", ".") if m else ""
        except:
            try:
                t = await page.inner_text('div.F7nice', timeout=1500)
                m = re.search(r"[\d,\.]+", t)
                veri["Puan"] = m.group().replace(",", ".") if m else ""
            except:
                veri["Puan"] = ""
    
        # Yorum Sayısı
        try:
            el = await page.query_selector('span[aria-label*="yorum"], span[aria-label*="review"]')
            lbl = await el.get_attribute("aria-label") if el else ""
            m = re.search(r"\d[\d\.]*", lbl or "")
            veri["Yorum Sayisi"] = m.group() if m else ""
        except:
            veri["Yorum Sayisi"] = ""
    
        # ✅ ADRES — aria-label'dan al: "Adres: Başak, Karapürçek..."
        try:
            el = await page.query_selector('button[data-item-id="address"]')
            if el:
                lbl = await el.get_attribute("aria-label") or ""
                # "Adres: " prefix'ini temizle
                adres = re.sub(r'^Adres:\s*', '', lbl, flags=re.IGNORECASE).strip()
                # Sondaki boşlukları temizle
                veri["Adres"] = adres.rstrip()
            else:
                veri["Adres"] = ""
        except:
            veri["Adres"] = ""
    
        # ✅ TELEFON — aria-label'dan al, sadece rakam bırak, 90 ile başlıyorsa 0'a çevir
        try:
            el = await page.query_selector('button[data-item-id^="phone:tel"]')
            if el:
                lbl = await el.get_attribute("aria-label") or ""
                # Sadece rakamları al
                tel = re.sub(r'\D', '', lbl)
                # +90 veya 90 ile başlıyorsa → 0 ile başlat
                if tel.startswith("90") and len(tel) == 12:
                    tel = "0" + tel[2:]
                veri["Telefon"] = tel
            else:
                veri["Telefon"] = ""
        except:
            veri["Telefon"] = ""
    
        # Web Sitesi
        try:
            el = await page.query_selector('a[data-item-id="authority"]')
            veri["Web Sitesi"] = (await el.get_attribute("href")).strip() if el else ""
        except:
            veri["Web Sitesi"] = ""
    
        # Çalışma Saatleri — aria-label'dan al: "24 saat açık·..."
        try:
            el = await page.query_selector('button[data-item-id="oh"]')
            if el:
                lbl = await el.get_attribute("aria-label") or ""
                # Sadece ilk kısım (· sonrasını at)
                veri["Calisma Saatleri"] = lbl.split("·")[0].strip()
            else:
                veri["Calisma Saatleri"] = ""
        except:
            veri["Calisma Saatleri"] = ""
    
        # Google Maps Linki (kısa)
        url = page.url
        m = re.search(r"(https://www\.google\.com/maps/place/[^@]+/@[\d\.,]+)", url)
        veri["Google Maps"] = m.group(1) if m else url.split("!")[0]
    
        # Görsel URL
        veri["Gorsel URL"] = await gorsel_url_al(page)
    
        return veri
    
    
    async def haritadan_veri_cek():
        from playwright.async_api import async_playwright
    
        isletmeler = []
        sorgu = f"{ARAMA_TERIMI} {SEHIR}"
    
        print("Tarayici baslatiliyor...")
        async with async_playwright() as p:
            browser = await p.chromium.launch(headless=False, args=["--no-sandbox"])
            context = await browser.new_context(locale="tr-TR")
            page = await context.new_page()
    
            url = "https://www.google.com/maps/search/" + sorgu.replace(" ", "+")
            print(f"Aciliyor: {url}")
            await page.goto(url, wait_until="domcontentloaded", timeout=30000)
            await page.wait_for_timeout(4000)
    
            for btn_text in ["Tumunu kabul et", "Accept all", "Kabul et"]:
                try:
                    await page.click(f'button:has-text("{btn_text}")', timeout=2000)
                    await page.wait_for_timeout(1000)
                    break
                except:
                    pass
    
            try:
                await page.wait_for_selector('div[role="feed"]', timeout=15000)
            except Exception as e:
                print(f"HATA: Liste paneli bulunamadi - {e}")
                await page.screenshot(path="hata_ekran.png")
                await browser.close()
                return []
    
            print("Sonuclar yukleniyor...")
            for i in range(MAX_ISLETME // 4 + 2):
                await page.evaluate("""
                    const feed = document.querySelector('div[role="feed"]');
                    if (feed) feed.scrollTop += 2000;
                """)
                await page.wait_for_timeout(1000)
                sys.stdout.write(f"\r  Scroll {i+1}...")
                sys.stdout.flush()
            print()
    
            kartlar = await page.query_selector_all('a.hfpxzc')
            print(f"{len(kartlar)} isletme bulundu, detaylar cekiliyor...\n")
    
            for i, kart in enumerate(kartlar[:MAX_ISLETME]):
                try:
                    await kart.click()
                    await page.wait_for_timeout(3000)
    
                    veri = await detay_cek(page)
                    isletmeler.append(veri)
    
                    ad  = veri.get("Firma Adi", "?")[:25]
                    tel = veri.get("Telefon", "") or "YOK"
                    adr = (veri.get("Adres", "") or "YOK")[:30]
                    img = "VAR" if veri.get("Gorsel URL") else "YOK"
                    print(f"  [{i+1:02d}] {ad:<25} | Tel:{tel:<16} | Adres:{adr:<30} | Img:{img}")
    
                except Exception as e:
                    print(f"  [{i+1:02d}] Hata: {e}")
                    continue
    
            await browser.close()
    
        return isletmeler
    
    
    def xlsx_kaydet(isletmeler, dosya):
        try:
            from openpyxl import Workbook
            from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
    
            wb = Workbook()
            ws = wb.active
            ws.title = "Isletmeler"
    
            basliklar = [
                "Firma Adi", "Telefon", "Adres", "Web Sitesi",
                "Kategori", "Puan", "Yorum Sayisi", "Calisma Saatleri",
                "Google Maps", "Gorsel URL"
            ]
    
            baslik_font = Font(name="Arial", bold=True, color="FFFFFF", size=11)
            baslik_fill = PatternFill("solid", start_color="1A73E8")
            kenar = Border(
                left=Side(style="thin"), right=Side(style="thin"),
                top=Side(style="thin"), bottom=Side(style="thin")
            )
    
            for col, b in enumerate(basliklar, 1):
                c = ws.cell(row=1, column=col, value=b)
                c.font = baslik_font
                c.fill = baslik_fill
                c.alignment = Alignment(horizontal="center", vertical="center")
                c.border = kenar
            ws.row_dimensions[1].height = 22
    
            for satir, isletme in enumerate(isletmeler, 2):
                renk = "EAF4FF" if satir % 2 == 0 else "FFFFFF"
                for col, b in enumerate(basliklar, 1):
                    deger = isletme.get(b, "")
                    c = ws.cell(row=satir, column=col, value=deger)
                    c.font = Font(name="Arial", size=10)
                    c.fill = PatternFill("solid", start_color=renk)
                    c.alignment = Alignment(vertical="center", wrap_text=(b == "Adres"))
                    c.border = kenar
                    if b == "Gorsel URL" and deger and deger.startswith("http"):
                        c.hyperlink = deger
                        c.font = Font(name="Arial", size=10, color="0563C1", underline="single")
    
            genislikler = [32, 18, 38, 28, 20, 7, 10, 18, 42, 18]
            for col, g in enumerate(genislikler, 1):
                ws.column_dimensions[ws.cell(row=1, column=col).column_letter].width = g
    
            ws.freeze_panes = "A2"
            path = f"{dosya}.xlsx"
            wb.save(path)
            print(f"XLSX kaydedildi: {path}")
        except Exception as e:
            print(f"XLSX hatasi: {e}")
            traceback.print_exc()
    
    
    def csv_kaydet(isletmeler, dosya):
        try:
            basliklar = [
                "Firma Adi", "Telefon", "Adres", "Web Sitesi",
                "Kategori", "Puan", "Yorum Sayisi", "Calisma Saatleri",
                "Google Maps", "Gorsel URL"
            ]
            path = f"{dosya}.csv"
            with open(path, "w", newline="", encoding="utf-8-sig") as f:
                w = csv.DictWriter(f, fieldnames=basliklar, extrasaction="ignore")
                w.writeheader()
                w.writerows(isletmeler)
            print(f"CSV  kaydedildi: {path}")
        except Exception as e:
            print(f"CSV hatasi: {e}")
    
    
    def main():
        print("=" * 60)
        print("  Google Maps Scraper v5 - Telefon/Adres Duzeltildi")
        print("=" * 60)
    
        try:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            isletmeler = loop.run_until_complete(haritadan_veri_cek())
            loop.close()
        except Exception as e:
            print(f"\nKRITIK HATA: {e}")
            traceback.print_exc()
            input("\nEnter'a basin...")
            return
    
        if not isletmeler:
            print("\nHic veri cekilemedi!")
            input("\nEnter'a basin...")
            return
    
        xlsx_kaydet(isletmeler, CIKTI_DOSYA)
        csv_kaydet(isletmeler, CIKTI_DOSYA)
    
        telefon_var = sum(1 for x in isletmeler if x.get("Telefon"))
        adres_var   = sum(1 for x in isletmeler if x.get("Adres"))
        gorsel_var  = sum(1 for x in isletmeler if x.get("Gorsel URL"))
        web_var     = sum(1 for x in isletmeler if x.get("Web Sitesi"))
    
        print(f"\n--- OZET ---")
        print(f"Toplam isletme : {len(isletmeler)}")
        print(f"Telefon        : {telefon_var}")
        print(f"Adres          : {adres_var}")
        print(f"Web Sitesi     : {web_var}")
        print(f"Gorsel URL     : {gorsel_var}")
        input("\nEnter'a basin...")
    
    
    if __name__ == "__main__":
        main()
  • 18-03-2026, 23:20:11
    #2
    Mail çekiyor mu uzun süredir böyle bir şey arıyorum
  • 18-03-2026, 23:22:29
    #3
    loocas adlı üyeden alıntı: mesajı görüntüle
    Mail çekiyor mu uzun süredir böyle bir şey arıyorum
    Google Benim İşletmem'de henüz e-posta verisi olmadığından maalesef çekmiyor.
  • 18-03-2026, 23:23:07
    #4
    teşekkürler
  • 18-03-2026, 23:23:32
    #5
    Inferno adlı üyeden alıntı: mesajı görüntüle
    Google Benim İşletmem'de henüz e-posta verisi olmadığından maalesef çekmiyor.
    Ben böyle bir şey arıyorum elinizde var mı ya da yardımcı olur musunuz, nasıl bulabilirim
  • 18-03-2026, 23:27:40
    #6
    loocas adlı üyeden alıntı: mesajı görüntüle
    Ben böyle bir şey arıyorum elinizde var mı ya da yardımcı olur musunuz, nasıl bulabilirim
    Elinizde e fatura sistemi varsa şirketlerin vergi numaralarını toplu sorgularsınız defaultpk tarzında bir mail gelecek oranın sonundaki uzantı firmanın domain uzantısıdır düz satıs, sales vb smtpleri boş mail göndererek deneyin (tor proxy ile yapın bunu) bir kaç mail çıkarırsınız bazılarında da kişisel mailler gelir.

    Şirket ünvanından ise vergi no öğrenebilrisniz google serp ile çıkan pek çok site mevcut serp api kullanarak ünvandan vergi no yapabilrsiniz.
  • 18-03-2026, 23:29:32
    #7
    netpositive adlı üyeden alıntı: mesajı görüntüle
    Elinizde e fatura sistemi varsa şirketlerin vergi numaralarını toplu sorgularsınız defaultpk tarzında bir mail gelecek oranın sonundaki uzantı firmanın domain uzantısıdır düz satıs, sales vb smtpleri boş mail göndererek deneyin (tor proxy ile yapın bunu) bir kaç mail çıkarırsınız bazılarında da kişisel mailler gelir.

    Şirket ünvanından ise vergi no öğrenebilrisniz google serp ile çıkan pek çok site mevcut serp api kullanarak ünvandan vergi no yapabilrsiniz.

    Dediğiniz sistem yoksa peki hocam
  • 18-03-2026, 23:33:20
    #8
    loocas adlı üyeden alıntı: mesajı görüntüle
    Dediğiniz sistem yoksa peki hocam
    Firma adını google'de otomatik aratıp "@gmail.com" "@outlook.com" "@hotmail.com" gibi içerir aramalar yaparak mail bulmanız olası.


    Bende tonla leads bilgisi var Google üzerinden alenileştirilmiş bilgilerin toplanması ile elde ettiğim yani KVKK uyumlu bilgiler. Bunları ileride leads platformu kurup sağlamayı düşünüyorum lead başı 5 ile 500 lira arasında (geri dönüş oranlarına göre değeri düşünülerek) Türkiye'de hemen hemen tüm ltd ve aşlerin satış, iletişim, ik mailleri var ama şahıs firmalarının KVKK gereğince mailleri yok.

    Sizce bu fikir başarılı olur muydu? SaaS altyapısında bu bilgileri sunmak.
  • 18-03-2026, 23:34:25
    #9
    loocas adlı üyeden alıntı: mesajı görüntüle
    Ben böyle bir şey arıyorum elinizde var mı ya da yardımcı olur musunuz, nasıl bulabilirim
    Google benim işletmemde bulunan firmaların çoğu gerçek vergi levhasına sahip bile değiller aynı zamanda çoğunun web sitesi bile yok. E-Posta adreslerini bulmak çok zor. E-Posta adresleri için şöyle bir şey yapılabilir, aldığınız excel listesinde web siteleri geldiyse o web sitelerine manuel girip iletişim sayfalarından maillerini toplayabilirsiniz.