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
| Ö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ı |
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ı |
- Python 3.10+
- Google Chrome tarayıcısı (sistemde yüklü olmalı)
- İnternet bağlantısı
# 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.txtChromeDriver,
webdriver-managertarafından otomatik indirilir; manuel kurulum gerekmez.
python google_maps_crawler_pro.py \
--file kombinasyonlar.txt \
--threads 4 \
--output sonuc.csv \
--headless| 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 |
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
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)
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]
- Dosya Okuma —
kombinasyonlar.txtiçindeki arama terimleri okunur. - ChromeDriver Hazırlığı — Driver yolu ana thread'de bir kez çözülür (paralel kilit çakışması önlenir).
- Kuyruk — Her
(anahtar_kelime, konum)çifti bir görev kuyruğuna eklenir. - Thread'ler — Belirtilen sayıda paralel thread kuyruktan görev alır.
- Tarayıcı — Her thread hazır driver yolu ile kendi Chrome oturumunu açar.
- Arama & Scroll — Google Maps'te arama yapılır, sonuçlar kaydırılarak yüklenir.
- Veri Çıkarma — Her işletme kartına tıklanır; detay panelinden bilgiler alınır.
- Kayıt — Veriler kilit mekanizması ile güvenli şekilde CSV'ye yazılır.
- Özet — İşlem bitince toplam kayıt sayısı ve istatistikler gösterilir.
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: 151google_maps_data.csv dosyası Excel veya Google Sheets ile doğrudan açılabilir.
Paralel çalışmada karşılaşılabilecek yaygın sorunlar ve kodda bunlara karşı alınan önlemler aşağıda açıklanmıştır.
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 durdurulduNeden olur?
--threads 5ile 5 thread eş zamanlı başlar.- Her thread kendi tarayıcısını açarken driver indirmeye çalışır.
webdriver-manageraynı anda tek kurulum yapılabilsin diye dosya kilidi kullanır.- Kilidi alamayan thread'ler bekler ve süre dolunca timeout verir.
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 driverChromeDriver 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_pathmain() 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 driverDü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 bulunduEski 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 --headlessBirden fazla thread aynı CSV dosyasına eş zamanlı yazarsa satırlar karışabilir veya dosya bozulabilir.
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.
Scroll sırasında aynı işletme birden fazla kez listelenebilir.
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)Selenium varsayılan ayarlarıyla navigator.webdriver özelliği görünür; Google bunu tespit edebilir.
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})"
)| 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ı |
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.
- 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
--headlesskullanı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.
- 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.
Proje Python type hints ile yazılmıştır. Statik analiz için:
pip install mypy
mypy google_maps_crawler_pro.pypip install ruff
ruff check google_maps_crawler_pro.py- Bu repoyu fork edin
- Yeni bir branch oluşturun (
git checkout -b ozellik/yeni-ozellik) - Değişikliklerinizi commit edin (
git commit -m 'Yeni özellik eklendi') - Branch'inizi push edin (
git push origin ozellik/yeni-ozellik) - Bir Pull Request açın
Bu proje MIT Lisansı altında yayınlanmaktadır.
Rojin Delal Dinçer
Projeyi faydalı bulduysanız yıldız vermeyi unutmayın!