· Engineering  · 3 min read

Neo4j + Exa + Tavily ile Otomatik İşletme Veri Zenginleştirme Pipeline'ı

Google Maps'ten bulunan işletmeleri Neo4j'e kaydedip Exa ve Tavily API'leri ile otomatik olarak zenginleştiren bir pipeline nasıl kurulur?

Google Maps'ten bulunan işletmeleri Neo4j'e kaydedip Exa ve Tavily API'leri ile otomatik olarak zenginleştiren bir pipeline nasıl kurulur?

Proje Nedir?

Bodrum’daki işletmeleri ve turistik yerleri dijital ortamda daha görünür kılmak için bir veri zenginleştirme pipeline’ı kurdum. Sistem üç aşamadan oluşuyor:

  1. Google Maps API → Yeni işletmeleri bulur ve Neo4j’ye kaydeder
  2. Place Enrichment → Exa + Tavily ile iletişim bilgileri ve sosyal medya linkleri bulur
  3. Auto Website Creation → Zenginleştirilen verilerle otomatik web sitesi oluşturur ve deploy eder

Bu yazıda ikinci aşamayı — Place Enrichment sistemini — detaylı olarak anlatacağım.

Mimari Genel Bakış

Google Maps API → Neo4j (ham veri)

           Place Enrichment (cron, her 2dk)

              Exa API (web, sosyal medya)
              Tavily API (telefon, email)

              Neo4j (zenginleştirilmiş veri)

           Auto Website Creation & Deploy

Neo4j Veri Modeli

Her işletme Neo4j’de bir Place node’u olarak tutuluyur. Temel alanlar:

CREATE (p:Place {
  name: "Bodrum Butik Otel",
  google_place_id: "ChIJ...",
  latitude: 37.034,
  longitude: 27.430,
  enriched: false,
  created_at: datetime()
})

enriched: false flag’i, Place Enrichment sisteminin hangi kayıtları işleyeceğini belirliyor.

Place Enrichment Sistemi

Cron Kurulumu

Sistem her 2 dakikada bir çalışacak şekilde crontab’a eklendi:

*/2 * * * * /Users/ebartan/clawd/agents/egecrew/projects/place-enrichment/run.sh

İşlem Akışı

Her çalışmada sistem şu adımları izliyor:

1. Neo4j’den zenginleştirilmemiş bir yer al:

query = """
MATCH (p:Place {enriched: false})
RETURN p LIMIT 1
"""

2. Exa API ile web arama:

Exa, nöral arama motoru özelliği sayesinde işletmenin web sitesini, sosyal medya profillerini ve fotoğraflarını buluyor:

exa_results = exa_client.search(
    f"{place_name} {location} official website",
    num_results=5,
    use_autoprompt=True,
    include_domains=["instagram.com", "facebook.com", "tripadvisor.com"]
)

3. Tavily API ile iletişim bilgisi arama:

Tavily, özellikle Türkçe formatlı telefon numaraları ve email adreslerini bulmakta güçlü:

tavily_results = tavily_client.search(
    f"{place_name} telefon iletişim email",
    search_depth="advanced",
    max_results=3
)

4. Verileri birleştir ve Neo4j’i güncelle:

enriched_data = {
    "website": extract_website(exa_results),
    "phone": extract_phone(tavily_results),
    "email": extract_email(tavily_results),
    "facebook_url": extract_social(exa_results, "facebook.com"),
    "instagram_url": extract_social(exa_results, "instagram.com"),
    "tripadvisor_url": extract_social(exa_results, "tripadvisor.com"),
    "photos": extract_photos(exa_results, limit=5),
    "enriched": True,
    "enriched_at": datetime.now().isoformat()
}

update_neo4j_place(place_id, enriched_data)

Bulunan Veri Türleri

Sistem başarıyla şu bilgileri buluyor:

Veri TürüKaynakBaşarı Oranı
Website URLExa~85%
Telefon (TR formatı)Tavily~70%
EmailTavily~45%
Facebook URLExa~60%
Instagram URLExa~55%
TripAdvisor URLExa~40%
Fotoğraflar (max 5)Exa~75%

Performans

  • Her çalışmada 1 işletme zenginleştiriliyor
  • 103 işletme için ~3.5 saat sürüyor (2 dakika × 103)
  • Log dosyası: logs/enricher.log

Yüksek hacimli senaryolar için paralel işleme eklenebilir, ancak API rate limit’lerine dikkat etmek gerekiyor.

Örnek Log Çıktısı

2026-03-16 14:32:01 INFO  Processing: Bodrum Butik Otel (ID: abc123)
2026-03-16 14:32:02 INFO  Exa search completed: 5 results
2026-03-16 14:32:03 INFO  Tavily search completed: 3 results
2026-03-16 14:32:03 INFO  Found: website=bodrumbutik.com, phone=+90 252 316 XXXX
2026-03-16 14:32:03 INFO  Found: instagram=@bodrumbutik, facebook=/bodrumbutik
2026-03-16 14:32:04 INFO  Neo4j updated successfully
2026-03-16 14:32:04 INFO  Enrichment complete for abc123

Zorluklar ve Çözümler

1. Türkçe karakter problemi: Exa ve Tavily API’lerine gönderilen sorgularda Türkçe karakterler (ş, ğ, ü, ö, ç, ı) doğru encode edilmeli.

2. Rate limiting: İki ayrı API kullanıldığı için her çalışmada sadece 1 işletme işleniyor. Bu, 2 dakikalık bekleme süresini verimli kullanıyor.

3. Veri kalitesi: Bazen yanlış telefon numaraları veya farklı işletmelere ait web siteleri dönüyor. Bunu azaltmak için işletme adı + şehir kombinasyonuyla arama yapıyorum.

Sonuç

Bu pipeline, manuel araştırma gerektiren işletme veri zenginleştirme sürecini tamamen otomatikleştiriyor. Exa’nın nöral arama motoru ve Tavily’nin web içeriği çıkarma yeteneği, Neo4j graph veritabanıyla birleşince güçlü bir veri katmanı oluşturuyor.

Bir sonraki yazıda bu zenginleştirilmiş verilerle otomatik web sitesi oluşturma ve deploy sürecini anlatacağım.


Kaynak kodu ve setup talimatları için GitHub repomu inceleyebilirsiniz.

Back to Blog

Related Posts

View All Posts »