Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🗺️ Google Maps İşletme Bilgisi Toplayıcı (Pro)

Python Selenium License: MIT

Google Maps üzerinden işletme bilgilerini otomatik olarak toplayan, çoklu thread destekli ve koordinat çıkarma özellikli profesyonel bir web kazıyıcı (scraper).

Yazar: Rojin Delal Dinçer


✨ Özellikler

Özellik Açıklama
🔍 Çoklu Arama Dosyadan okunan anahtar kelime + konum kombinasyonlarını sırayla işler
🧵 Paralel Thread Birden fazla tarayıcı oturumu ile hızlı veri toplama
📍 Koordinat Desteği Her işletme için enlem/boylam bilgisi çıkarır
📊 CSV Çıktısı UTF-8 BOM ile Excel uyumlu CSV dosyası üretir
🎨 Renkli Loglama Terminalde anlaşılır, zaman damgalı log mesajları
👻 Headless Mod Görünmez tarayıcı ile arka planda çalışma
🛡️ Bot Tespiti Önleme Temel anti-detection ayarları
🔒 Thread-Safe Yazım Paralel thread'lerde güvenli CSV yazımı

📋 Toplanan Veriler

Her işletme için aşağıdaki alanlar CSV dosyasına kaydedilir:

Sütun Açıklama
isim İşletme adı
telefon Telefon numarası
website Web sitesi URL'si
adres Fiziksel adres
puan Google puanı (ör. 4.5)
yorum_sayisi Toplam yorum sayısı
calisma_saatleri Çalışma saatleri
kategori İşletme kategorisi
keyword Arama yapılan anahtar kelime + konum
enlem Enlem koordinatı
boylam Boylam koordinatı

🚀 Kurulum

Gereksinimler

  • Python 3.10+
  • Google Chrome tarayıcısı (sistemde yüklü olmalı)
  • İnternet bağlantısı

Adımlar

# 1. Repoyu klonlayın
git clone https://github.com/kullanici/google_maps_crawler.git
cd google_maps_crawler

# 2. Sanal ortam oluşturun (önerilir)
python -m venv venv
source venv/bin/activate        # Linux / macOS
# venv\Scripts\activate         # Windows

# 3. Bağımlılıkları yükleyin
pip install -r requirements.txt

ChromeDriver, webdriver-manager tarafından otomatik indirilir; manuel kurulum gerekmez.


📖 Kullanım

Temel Kullanım

python google_maps_crawler_pro.py \
  --file kombinasyonlar.txt \
  --threads 4 \
  --output sonuc.csv \
  --headless

Parametreler

Parametre Zorunlu Varsayılan Açıklama
--file ✅ Evet Anahtar kelime dosyasının yolu
--threads Hayır 3 Paralel çalışacak thread sayısı
--output Hayır google_maps_data.csv Çıktı CSV dosyası
--headless Hayır Kapalı Tarayıcıyı görünmez modda çalıştırır

Keyword Dosyası Formatı

kombinasyonlar.txt dosyasında her satır bir arama ifadesi temsil eder:

# Yorum satırları # ile başlar
restoran, İstanbul Kadıköy
kuaför, Ankara Çankaya
eczane, İzmir Bornova
doktor                          # Sadece anahtar kelime (konum boş)

Format: anahtar_kelime, konum veya sadece anahtar_kelime


🏗️ Proje Yapısı

google_maps_crawler/
├── google_maps_crawler_pro.py   # Ana scraper uygulaması
├── requirements.txt             # Python bağımlılıkları
├── README.md                    # Bu dosya
├── kombinasyonlar_ornek.txt     # Örnek arama dosyası
└── kombinasyonlar.txt           # Kendi arama listeniz (siz oluşturursunuz)

⚙️ Nasıl Çalışır?

flowchart TD
    A[Keyword dosyası okunur] --> B[ChromeDriver tek seferlik hazırlanır]
    B --> C[Görev kuyruğu oluşturulur]
    C --> D[Thread havuzu başlatılır]
    D --> E[Her thread: Chrome başlatır]
    E --> F[Google Maps arama URL'si açılır]
    F --> G[Sonuç listesi scroll edilir]
    G --> H[Her işletmeye tıklanır]
    H --> I[Detay bilgileri çıkarılır]
    I --> J[CSV'ye thread-safe yazılır]
    J --> K[Tüm thread'ler bitince özet gösterilir]
Loading
  1. Dosya Okumakombinasyonlar.txt içindeki arama terimleri okunur.
  2. ChromeDriver Hazırlığı — Driver yolu ana thread'de bir kez çözülür (paralel kilit çakışması önlenir).
  3. Kuyruk — Her (anahtar_kelime, konum) çifti bir görev kuyruğuna eklenir.
  4. Thread'ler — Belirtilen sayıda paralel thread kuyruktan görev alır.
  5. Tarayıcı — Her thread hazır driver yolu ile kendi Chrome oturumunu açar.
  6. Arama & Scroll — Google Maps'te arama yapılır, sonuçlar kaydırılarak yüklenir.
  7. Veri Çıkarma — Her işletme kartına tıklanır; detay panelinden bilgiler alınır.
  8. Kayıt — Veriler kilit mekanizması ile güvenli şekilde CSV'ye yazılır.
  9. Özet — İşlem bitince toplam kayıt sayısı ve istatistikler gösterilir.

📊 Örnek Çıktı

Terminalde renkli loglar görürsünüz:

Terminal çıktısı (metin)
$ python3 google_maps_crawler_pro.py \
    --file kombinasyonlar_ornek.txt \
    --threads 3 \
    --output google_maps_data.csv \
    --headless

[2026-08-03 22:05:00 - BİLGİ]    Toplam 5 arama kombinasyonu işlenecek
[2026-08-03 22:05:00 - BİLGİ]    3 thread ile çalıştırılacak
[2026-08-03 22:05:00 - BİLGİ]    Çıktı dosyası: google_maps_data.csv
[2026-08-03 22:05:00 - BİLGİ]    ChromeDriver indiriliyor / doğrulanıyor (tek seferlik)...
[2026-08-03 22:05:02 - BİLGİ]    ChromeDriver hazır: /home/charlie/.wdm/drivers/chromedriver/linux64/...
[2026-08-03 22:05:02 - THREAD-1] Tarayıcı başlatıldı
[2026-08-03 22:05:03 - THREAD-2] Tarayıcı başlatıldı
[2026-08-03 22:05:04 - THREAD-3] Tarayıcı başlatıldı
[2026-08-03 22:05:08 - THREAD-1] 'restoran İstanbul Kadıköy' için 42 işletme bulundu
[2026-08-03 22:07:30 - THREAD-1] ✅ 'restoran İstanbul Kadıköy' - 38 işletme kaydedildi
[2026-08-03 22:15:00 - BİLGİ]    Tüm thread'ler tamamlandı - Toplam süre: 600.42 saniye
[2026-08-03 22:15:00 - BİLGİ]    📊 SONUÇ: Toplam 156 işletme kaydedildi
[2026-08-03 22:15:00 - BİLGİ]    📞 Telefon: 142
[2026-08-03 22:15:00 - BİLGİ]    🌐 Website: 98
[2026-08-03 22:15:00 - BİLGİ]    ⭐ Puan: 156
[2026-08-03 22:15:00 - BİLGİ]    📍 Koordinat: 151

google_maps_data.csv dosyası Excel veya Google Sheets ile doğrudan açılabilir.


🔧 Sorun Giderme ve Kodda Alınan Önlemler

Paralel çalışmada karşılaşılabilecek yaygın sorunlar ve kodda bunlara karşı alınan önlemler aşağıda açıklanmıştır.


1. ChromeDriver Kilit Zaman Aşımı (webdriver-manager lock)

Sorun

Birden fazla thread aynı anda ChromeDriverManager().install() çağırdığında şu hata oluşur:

Terminal çıktısı (hata — metin)
$ python3 google_maps_crawler_pro.py --file test_keywords.txt --threads 5

[2026-08-03 21:57:36 - BİLGİ]    Dosyadan 2988 keyword/location çifti okundu
[2026-08-03 21:57:36 - BİLGİ]    Toplam 2988 arama kombinasyonu işlenecek
[2026-08-03 21:57:36 - BİLGİ]    5 thread ile çalıştırılacak
[2026-08-03 21:57:36 - BİLGİ]    Çıktı dosyası: google_maps_data.csv

# ~60 saniye sonra tüm thread'ler aynı hatayı verir:
[2026-08-03 21:58:36 - HATA]   Thread-1: Tarayıcı başlatılamadı: Timed out waiting for webdriver-manager lock: /home/charlie/.wdm/.wdm-lock-chromedriver-linux64
[2026-08-03 21:58:36 - HATA]   Thread-2: Tarayıcı başlatılamadı: Timed out waiting for webdriver-manager lock: /home/charlie/.wdm/.wdm-lock-chromedriver-linux64
[2026-08-03 21:58:36 - HATA]   Thread-3: Tarayıcı başlatılamadı: Timed out waiting for webdriver-manager lock: /home/charlie/.wdm/.wdm-lock-chromedriver-linux64
[2026-08-03 21:58:36 - HATA]   Thread-4: Tarayıcı başlatılamadı: Timed out waiting for webdriver-manager lock: /home/charlie/.wdm/.wdm-lock-chromedriver-linux64
[2026-08-03 21:58:36 - HATA]   Thread-5: Tarayıcı başlatılamadı: Timed out waiting for webdriver-manager lock: /home/charlie/.wdm/.wdm-lock-chromedriver-linux64

^C
[2026-08-03 21:58:43 - UYARI] Kullanıcı tarafından durduruldu

Neden olur?

  • --threads 5 ile 5 thread eş zamanlı başlar.
  • Her thread kendi tarayıcısını açarken driver indirmeye çalışır.
  • webdriver-manager aynı anda tek kurulum yapılabilsin diye dosya kilidi kullanır.
  • Kilidi alamayan thread'ler bekler ve süre dolunca timeout verir.

Eski (sorunlu) yaklaşım

Her thread içinde ayrı install() çağrısı yapılıyordu:

# ❌ YANLIŞ: Her thread aynı anda install() çağırır → kilit çakışması
def setup_browser(thread_id, is_headless=True):
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=chrome_options)
    return driver

Kodda alınan önlem

ChromeDriver yolu ana thread'de bir kez hazırlanır, tüm worker thread'lere parametre olarak aktarılır:

# Modül seviyesinde önbellek
_chromedriver_path: Optional[str] = None

def resolve_chromedriver_path() -> str:
    """Driver yolunu tek seferlik çözer; paralel install() çağrılarını engeller."""
    global _chromedriver_path

    if _chromedriver_path is None:
        log_info("ChromeDriver indiriliyor / doğrulanıyor (tek seferlik)...")
        _chromedriver_path = ChromeDriverManager().install()
        log_info(f"ChromeDriver hazır: {_chromedriver_path}")

    return _chromedriver_path

main() içinde thread'ler başlamadan önce çağrılır:

# ✅ DOĞRU: Thread'ler başlamadan önce driver hazırlanır
chromedriver_path = resolve_chromedriver_path()

for i in range(thread_count):
    thread = threading.Thread(
        target=worker,
        args=(i + 1, task_queue, args.output, chromedriver_path, args.headless),
        daemon=True,
    )
    thread.start()

Her thread hazır yolu kullanır; tekrar install() çağırmaz:

# ✅ DOĞRU: Paylaşılan driver yolu ile tarayıcı açılır
def setup_browser(thread_id, chromedriver_path, is_headless=True):
    service = Service(chromedriver_path)  # install() yok
    driver = webdriver.Chrome(service=service, options=chrome_options)
    return driver

Düzeltme sonrası beklenen terminal çıktısı

Düzeltmeden sonra ChromeDriver thread'ler başlamadan önce hazırlanır; tüm thread'ler sorunsuz açılır:

Terminal çıktısı (düzeltme sonrası — metin)
$ python3 google_maps_crawler_pro.py --file test_keywords.txt --threads 5 --headless

[2026-08-03 22:01:00 - BİLGİ]    Dosyadan 2988 keyword/location çifti okundu
[2026-08-03 22:01:00 - BİLGİ]    Toplam 2988 arama kombinasyonu işlenecek
[2026-08-03 22:01:00 - BİLGİ]    5 thread ile çalıştırılacak
[2026-08-03 22:01:00 - BİLGİ]    Çıktı dosyası: google_maps_data.csv

# ✅ Driver ana thread'de bir kez hazırlanır (kilit çakışması yok)
[2026-08-03 22:01:00 - BİLGİ]    ChromeDriver indiriliyor / doğrulanıyor (tek seferlik)...
[2026-08-03 22:01:02 - BİLGİ]    ChromeDriver hazır: /home/charlie/.wdm/drivers/chromedriver/linux64/...

# ✅ Tüm thread'ler hazır yolu kullanarak tarayıcıyı açar
[2026-08-03 22:01:04 - THREAD-1] Tarayıcı başlatıldı
[2026-08-03 22:01:04 - THREAD-2] Tarayıcı başlatıldı
[2026-08-03 22:01:04 - THREAD-3] Tarayıcı başlatıldı
[2026-08-03 22:01:05 - THREAD-4] Tarayıcı başlatıldı
[2026-08-03 22:01:05 - THREAD-5] Tarayıcı başlatıldı
[2026-08-03 22:01:08 - THREAD-1] Google Maps açılıyor...
[2026-08-03 22:01:12 - THREAD-1] 'kuaför Ankara' için 35 işletme bulundu

Hâlâ hata alırsanız

Eski bir kilit dosyası takılı kalmış olabilir:

rm -f ~/.wdm/.wdm-lock-chromedriver-linux64
python3 google_maps_crawler_pro.py --file kombinasyonlar.txt --threads 3 --headless

2. Paralel CSV Yazımında Veri Bozulması

Sorun

Birden fazla thread aynı CSV dosyasına eş zamanlı yazarsa satırlar karışabilir veya dosya bozulabilir.

Kodda alınan önlem

Modül seviyesinde threading.Lock ile korumalı yazım:

# Thread-safe CSV yazımı için kilit
csv_lock: Final[threading.Lock] = threading.Lock()

def write_business_data_to_csv(output_file, business_data):
    """Tüm CSV yazımları kilit altında yapılır."""
    with csv_lock:
        file_exists = os.path.isfile(output_file)
        with open(output_file, "a", newline="", encoding="utf-8-sig") as f:
            writer = csv.DictWriter(f, fieldnames=CSV_FIELDNAMES)
            if not file_exists:
                writer.writeheader()
            writer.writerows(business_data)

with csv_lock: bloğu sayesinde aynı anda yalnızca bir thread dosyaya yazar.


3. Aynı İşletmenin Tekrar Kaydedilmesi

Sorun

Scroll sırasında aynı işletme birden fazla kez listelenebilir.

Kodda alınan önlem

Her arama için processed_names set'i ile benzersizlik kontrolü:

business_data = []
processed_names: set[str] = set()

for element in elements[:50]:
    business_info = extract_business_info_from_detail_page(driver, thread_id)
    business_name = business_info.get("isim", "")

    # Aynı isimli işletme tekrar eklenmez
    if business_name and business_name not in processed_names:
        processed_names.add(business_name)
        business_data.append(business_info)

4. Bot Tespiti Riski

Sorun

Selenium varsayılan ayarlarıyla navigator.webdriver özelliği görünür; Google bunu tespit edebilir.

Kodda alınan önlem

Chrome seçenekleri ve JavaScript ile temel gizleme:

chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option("useAutomationExtension", False)

driver = webdriver.Chrome(service=service, options=chrome_options)

# webdriver bayrağını gizle
driver.execute_script(
    "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
)

Özet Tablo

Sorun Belirti Kodda alınan önlem
ChromeDriver kilit çakışması Timed out waiting for webdriver-manager lock resolve_chromedriver_path() ile tek seferlik kurulum
CSV bozulması Karışık/bozuk satırlar csv_lock ile thread-safe yazım
Tekrarlayan kayıtlar Aynı işletme birden fazla satır processed_names set kontrolü
Bot tespiti CAPTCHA / engelleme Anti-detection Chrome ayarları

⚠️ Önemli Notlar

Yasal Uyarı

Bu araç yalnızca eğitim ve araştırma amaçlıdır. Google Maps Hizmet Şartları'na uygun kullanım sorumluluğu size aittir. Ticari veya yoğun kullanımda Google'ın resmi API'lerini tercih edin.

Performans İpuçları

  • Thread sayısı: Sisteminize göre 2–5 arası önerilir. Çok yüksek değerler IP engeline yol açabilir.
  • Headless mod: Sunucu veya CI ortamlarında --headless kullanın.
  • Bekleme süreleri: Google arayüzü değişirse selector'lar güncellenmeli; scroll ve tıklama gecikmeleri ayarlanabilir.
  • ChromeDriver hatası: Yukarıdaki Sorun Giderme bölümüne bakın.

Bilinen Sınırlamalar

  • Her arama için en fazla 50 işletme işlenir (performans sınırı).
  • Google Maps arayüz güncellemeleri CSS/XPath seçicilerini etkileyebilir.
  • CAPTCHA veya rate limiting durumunda manuel müdahale gerekebilir.

🛠️ Geliştirme

Tip Kontrolü

Proje Python type hints ile yazılmıştır. Statik analiz için:

pip install mypy
mypy google_maps_crawler_pro.py

Kod Stili

pip install ruff
ruff check google_maps_crawler_pro.py

🤝 Katkıda Bulunma

  1. Bu repoyu fork edin
  2. Yeni bir branch oluşturun (git checkout -b ozellik/yeni-ozellik)
  3. Değişikliklerinizi commit edin (git commit -m 'Yeni özellik eklendi')
  4. Branch'inizi push edin (git push origin ozellik/yeni-ozellik)
  5. Bir Pull Request açın

📄 Lisans

Bu proje MIT Lisansı altında yayınlanmaktadır.


👤 Yazar

Rojin Delal Dinçer


⭐ Teşekkürler

Projeyi faydalı bulduysanız yıldız vermeyi unutmayın!

About

Python3 Selenium-based Google Maps scraper for SEO and research purposes.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages