• 22-07-2026, 23:16:38
    #1
    Merhaba LinkedIn üzerinden şöyle bir isim soyisim mesleı alıcı bot yazdım ama bot çalışmıyor yardımcı olur musunuz




    import sys
    import subprocess
    import threading
    import time
    import random
    import os
    import queue
    import tkinter as tk
    from tkinter import ttk

    # ==========================================
    # 1. OTOMATİK KÜTÜPHANE KONTROL VE KURULUMU
    # ==========================================
    def install_dependencies():
    required_packages = ["selenium==4.18.1", "pandas", "openpyxl"]
    missing_packages = []

    try:
    import selenium
    except ImportError:
    missing_packages.append("selenium==4.18.1")

    try:
    import pandas
    except ImportError:
    missing_packages.append("pandas")

    try:
    import openpyxl
    except ImportError:
    missing_packages.append("openpyxl")

    if missing_packages:
    print(f"Eksik kütüphaneler tespit edildi, kuruluyor: {missing_packages}")
    print("Lütfen bekleyin (1-2 dakika sürebilir)...")
    subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", *missing_packages])
    print("Kurulum tamamlandı. Uygulama başlatılıyor...")

    install_dependencies()

    import pandas as pd
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException, NoSuchElementException

    # ==========================================
    # 2. SELENIUM SCRAPER MOTORU
    # ==========================================
    class LinkedInScraperEngine:
    def __init__(self, log_queue):
    self.log_queue = log_queue
    self.driver = None
    self.wait = None
    self.employees_data = set()

    self.next_pause_target = random.randint(30, 70)
    self.next_save_target = random.randint(25, 65)

    if not os.path.exists("data"):
    os.makedirs("data")

    def log(self, message):
    self.log_queue.put(message)

    def initialize_driver(self):
    if self.driver is not None:
    self.log("Tarayıcı zaten açık.")
    return

    self.log("Tarayıcı başlatılıyor... Lütfen bekleyin.")
    options = webdriver.ChromeOptions()
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_argument("start-maximized")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExte nsion', False)
    prefs = {"profile.default_content_setting_values.notificat ions": 2}
    options.add_experimental_option("prefs", prefs)

    self.driver = webdriver.Chrome(options=options)
    self.driver.execute_cdp_cmd("Page.addScriptToEvalu ateOnNewDocument", {
    "source": """
    Object.defineProperty(navigator, 'webdriver', {
    get: () => undefined
    })
    """
    })
    self.wait = WebDriverWait(self.driver, 15) # Bekleme süresi 15 saniyeye çıkarıldı
    self.driver.get("https://www.linkedin.com/login")
    self.log("Lütfen açılan tarayıcıda LinkedIn'e giriş yapın ve ardından arayüzden işlemleri seçin.")

    def human_like_scroll(self, scroll_pauses=3):
    try:
    total_height = int(self.driver.execute_script("return document.body.scrollHeight"))
    for i in range(1, scroll_pauses + 1):
    scroll_to = int(total_height * (i / scroll_pauses))
    self.driver.execute_script(f"window.scrollTo(0, {scroll_to});")
    time.sleep(random.uniform(1.2, 2.5))
    self.driver.execute_script("window.scrollBy(0, -300);")
    time.sleep(random.uniform(1.0, 1.5))
    except Exception as e:
    self.log(f"Kaydırma sırasında uyarı: {e}")

    def extract_name_parts(self, full_name):
    if not full_name: return "", ""
    clean_name = full_name.split('n')[0].strip()
    parts = clean_name.split()
    if len(parts) > 1:
    return " ".join(parts[:-1]), parts[-1]
    return clean_name, ""

    def export_data_to_files(self, is_auto_save=False):
    if not self.employees_data:
    return

    data_list = [{"Ad": emp[0], "Soyad": emp[1], "Sirket_ve_Unvan": emp[2]} for emp in self.employees_data]
    df = pd.DataFrame(data_list)
    df.drop_duplicates(subset=["Ad", "Soyad", "Sirket_ve_Unvan"], inplace=True)

    excel_path = os.path.join("data", "linkedin_verileri.xlsx")
    csv_path = os.path.join("data", "linkedin_verileri.csv")

    df.to_excel(excel_path, index=False, engine='openpyxl')
    df.to_csv(csv_path, index=False, encoding='utf-8-sig')

    if not is_auto_save:
    self.log(f"BAŞARILI! Toplam {len(df)} benzersiz kayıt dosyaya yazıldı.")
    self.log(f"Dosya yolları:n{os.path.abspath(excel_path)}")

    def check_anti_ban_and_save(self):
    current_count = len(self.employees_data)

    if current_count >= self.next_pause_target:
    sleep_time = random.uniform(15.0, 20.0)
    self.log(f"n--- RASTGELE DİNLENME MOLASI ---")
    self.log(f"İnsan davranışı simüle ediliyor... {sleep_time:.1f} saniye bekleniyor.")
    time.sleep(sleep_time)
    self.next_pause_target = current_count + random.randint(30, 70)
    self.log("Dinlenme bitti, okumaya devam ediliyor...n")

    if current_count >= self.next_save_target:
    self.log(f"n--- OTOMATİK ARA KAYIT ---")
    self.log(f"Arka planda Excel'e kaydediliyor... (Toplam ulaşılan: {current_count} kişi)")
    self.export_data_to_files(is_auto_save=True)
    sleep_time = random.uniform(10.0, 20.0)
    self.log(f"Kayıt sonrası {sleep_time:.1f} saniye dinleniliyor...")
    time.sleep(sleep_time)
    self.next_save_target = current_count + random.randint(25, 65)
    self.log("Kayıt ve dinlenme tamamlandı, taramaya devam ediliyor...n")

    def scrape_profile_and_sidebar(self):
    if not self.driver:
    self.log("HATA: Önce tarayıcıyı başlatmalısınız!")
    return

    self.log("Profil ve sağ panel taranıyor... Lütfen tarayıcıya dokunmayın.")
    time.sleep(2) # Sayfanın ve DOM'un tam oturması için mutlak bekleme eklendi
    added_count = 0

    # Ana Profil (Daha esnek seçiciler ve WebDriverWait)
    try:
    self.wait.until(EC.presence_of_element_located((By .TAG_NAME, "h1")))
    main_name = self.driver.find_element(By.TAG_NAME, "h1").text.strip()

    try:
    # 'text-body-medium.break-words' yerine daha geniş bir class
    main_company = self.driver.find_element(By.CSS_SELECTOR, ".text-body-medium").text.strip()
    except NoSuchElementException:
    main_company = "Unvan/Şirket Bulunamadı"

    f_name, l_name = self.extract_name_parts(main_name)
    if f_name:
    self.employees_data.add((f_name, l_name, main_company))
    added_count += 1
    self.log(f"Ana Profil Eklendi: {f_name} {l_name} | {main_company}")
    except Exception as e:
    self.log("Ana profil h1 etiketi bulunamadı. Sayfanın tam yüklendiğinden emin olun.")

    self.human_like_scroll(scroll_pauses=4) # Yan panelin yüklenmesi için scroll

    # Sağ Panel
    try:
    # Sadece 'aside' içindeki 'li' etiketlerini bul (En güvenli yöntem)
    sidebar_elements = self.driver.find_elements(By.XPATH, "//aside//li")
    for elem in sidebar_elements:
    try:
    # İsim etiketi için çoklu alternatif
    name_elem = elem.find_element(By.CSS_SELECTOR, ".artdeco-entity-lockup__title, span[dir='ltr']")
    name_text = name_elem.text.strip().split('n')[0]

    try:
    title_text = elem.find_element(By.CSS_SELECTOR, ".artdeco-entity-lockup__subtitle").text.strip()
    except:
    title_text = "Belirtilmemiş"

    f_name, l_name = self.extract_name_parts(name_text)
    # "LinkedIn Üyesi" veya reklam olabilecek girdileri engelle
    if f_name and "LinkedIn" not in f_name:
    before = len(self.employees_data)
    self.employees_data.add((f_name, l_name, title_text))
    if len(self.employees_data) > before:
    added_count += 1
    except NoSuchElementException:
    continue

    self.log(f"İşlem Tamam. Bu sayfadan toplam {added_count} yeni kişi eklendi.")
    self.check_anti_ban_and_save()

    except Exception as e:
    self.log("Sağ panel taramasında veri bulunamadı veya panel yok.")

    def scrape_company_people(self):
    if not self.driver:
    self.log("HATA: Önce tarayıcıyı başlatmalısınız!")
    return

    self.log("Şirket çalışanları taranıyor... Lütfen sayfaya müdahale etmeyin.")
    time.sleep(2)

    try:
    self.wait.until(EC.presence_of_element_located((By .TAG_NAME, "h1")))
    company_header = self.driver.find_element(By.TAG_NAME, "h1").text.strip()
    except:
    company_header = "Bilinmeyen Şirket"

    # Şirket listesi sayfasında olduğumuzu teyit et
    try:
    self.wait.until(EC.presence_of_element_located((By .CSS_SELECTOR, ".artdeco-entity-lockup__title")))
    except:
    self.log("Uyarı: Ekranda çalışan kartı bulunamadı. Şirketin 'Kişiler' sekmesinde misiniz?")
    return

    last_height = self.driver.execute_script("return document.body.scrollHeight")
    attempts = 0

    while True:
    try:
    # Daha genel kart seçicileri
    cards = self.driver.find_elements(By.CSS_SELECTOR, "li .artdeco-entity-lockup, .org-people-profile-card")
    initial_count = len(self.employees_data)

    for card in cards:
    try:
    name_text = card.find_element(By.CSS_SELECTOR, ".artdeco-entity-lockup__title, span[dir='ltr']").text.strip()
    try:
    subtitle_text = card.find_element(By.CSS_SELECTOR, ".artdeco-entity-lockup__subtitle").text.strip()
    except:
    subtitle_text = company_header

    f_name, l_name = self.extract_name_parts(name_text)
    if f_name and "LinkedIn" not in f_name:
    self.employees_data.add((f_name, l_name, subtitle_text))
    except NoSuchElementException:
    continue

    new_count = len(self.employees_data)

    if new_count == initial_count:
    attempts += 1
    else:
    attempts = 0
    self.log(f"Tarama devam ediyor... Anlık toplam kişi: {new_count}")

    self.check_anti_ban_and_save()

    if attempts >= 3:
    self.log("Listenin sonuna gelindi veya yeni veri yüklenmiyor. Tarama bitti.")
    break

    self.human_like_scroll(scroll_pauses=2)
    new_height = self.driver.execute_script("return document.body.scrollHeight")

    if new_height == last_height:
    attempts += 1
    else:
    last_height = new_height

    except Exception as e:
    self.log(f"Tarama sırasında bir hata oluştu: {e}")
    break

    def export_and_close(self):
    if not self.employees_data:
    self.log("Dışa aktarılacak veri bulunamadı. Tarayıcı kapatılıyor.")
    else:
    self.log("Tüm işlemler bitti. Final kayıtlar Excel ve CSV'ye işleniyor...")
    self.export_data_to_files(is_auto_save=False)

    if self.driver:
    self.driver.quit()
    self.driver = None
    self.log("Tarayıcı güvenli bir şekilde kapatıldı.")

    # ==========================================
    # 3. KULLANICI ARAYÜZÜ (GUI)
    # ==========================================
    class LinkedInScraperGUI:
    def __init__(self, root):
    self.root = root
    self.root.title("LinkedIn Bot & Ağ Gezgini")
    self.root.geometry("650x550")
    self.root.configure(padx=20, pady=20)

    self.log_queue = queue.Queue()
    self.scraper = LinkedInScraperEngine(self.log_queue)

    self.create_widgets()
    self.root.after(100, self.process_log_queue)

    def create_widgets(self):
    info_label = ttk.Label(self.root, text="LinkedIn Veri Çekme Otomasyonu", font=("Arial", 14, "bold"))
    info_label.pack(pady=(0, 15))

    btn_frame = ttk.Frame(self.root)
    btn_frame.pack(fill=tk.X, pady=10)

    self.btn_start = ttk.Button(btn_frame, text="1. Tarayıcıyı Başlat ve Giriş Yap", command=self.start_browser_thread)
    self.btn_start.pack(fill=tk.X, pady=5)

    self.btn_profile = ttk.Button(btn_frame, text="2. Açık Olan Kişi Profilini ve Sağ Paneli Tara", command=self.scrape_profile_thread)
    self.btn_profile.pack(fill=tk.X, pady=5)

    self.btn_company = ttk.Button(btn_frame, text="3. Açık Olan Şirketin Çalışanlarını Tara", command=self.scrape_company_thread)
    self.btn_company.pack(fill=tk.X, pady=5)

    self.btn_export = ttk.Button(btn_frame, text="4. Verileri Kaydet ve Uygulamayı Kapat", command=self.export_thread)
    self.btn_export.pack(fill=tk.X, pady=5)

    log_label = ttk.Label(self.root, text="İşlem Kayıtları (Log):")
    log_label.pack(anchor=tk.W, pady=(15, 5))

    self.log_text = tk.Text(self.root, height=12, state='disabled', bg="#f0f0f0", font=("Consolas", 9))
    self.log_text.pack(fill=tk.BOTH, expand=True)

    def write_log(self, message):
    self.log_text.config(state='normal')
    self.log_text.insert(tk.END, f"> {message}n")
    self.log_text.see(tk.END)
    self.log_text.config(state='disabled')

    def process_log_queue(self):
    try:
    while True:
    msg = self.log_queue.get_nowait()
    self.write_log(msg)
    except queue.Empty:
    pass
    finally:
    self.root.after(100, self.process_log_queue)

    def start_browser_thread(self):
    threading.Thread(target=self.scraper.initialize_dr iver, daemon=True).start()

    def scrape_profile_thread(self):
    threading.Thread(target=self.scraper.scrape_profil e_and_sidebar, daemon=True).start()

    def scrape_company_thread(self):
    threading.Thread(target=self.scraper.scrape_compan y_people, daemon=True).start()

    def export_thread(self):
    def task():
    self.scraper.export_and_close()
    self.log_queue.put("Tüm işlemler bitti. Pencereyi kapatabilirsiniz.")
    threading.Thread(target=task, daemon=True).start()

    if __name__ == "__main__":
    root = tk.Tk()

    style = ttk.Style()
    if "clam" in style.theme_names():
    style.theme_use("clam")

    app = LinkedInScraperGUI(root)

    def on_closing():
    if app.scraper.employees_data:
    print("nPencere kapatıldı. Veriler otomatik olarak Excel'e yedekleniyor...")
    try:
    app.scraper.export_data_to_files(is_auto_save=Fals e)
    print("Kayıt başarılı!")
    except:
    pass

    if app.scraper.driver:
    try:
    app.scraper.driver.quit()
    except:
    pass

    root.destroy()

    root.protocol("WM_DELETE_WINDOW", on_closing)
    root.mainloop()
  • 22-07-2026, 23:21:14
    #2
    Kod yapısına baktığımda sadece syntax/girinti hatası değil, LinkedIn tarafında da sorun olabilir; class isimleri ve CSS selector’ları LinkedIn’in güncel DOM yapısıyla uyuşmuyor olabilir, ayrıca LinkedIn bot tespit sistemleri Selenium ile yapılan otomasyonları kısıtlayabiliyor. Aldığınız hata mesajını ve hangi aşamada veri çekemediğini paylaşırsanız daha net bakabiliriz hocam..
  • 22-07-2026, 23:22:16
    #3
    dadayli adlı üyeden alıntı: mesajı görüntüle
    Kod yapısına baktığımda sadece syntax/girinti hatası değil, LinkedIn tarafında da sorun olabilir; class isimleri ve CSS selector’ları LinkedIn’in güncel DOM yapısıyla uyuşmuyor olabilir, ayrıca LinkedIn bot tespit sistemleri Selenium ile yapılan otomasyonları kısıtlayabiliyor. Aldığınız hata mesajını ve hangi aşamada veri çekemediğini paylaşırsanız daha net bakabiliriz hocam..
    Bu arada selector tarafını da kontrol etmekte fayda var; LinkedIn arayüzünü sık değiştirdiği için eski class ve CSS selector değerleri artık elementleri bulamıyor olabilir hocam
  • 22-07-2026, 23:23:04
    #4
    dadayli adlı üyeden alıntı: mesajı görüntüle
    Kod yapısına baktığımda sadece syntax/girinti hatası değil, LinkedIn tarafında da sorun olabilir; class isimleri ve CSS selector’ları LinkedIn’in güncel DOM yapısıyla uyuşmuyor olabilir, ayrıca LinkedIn bot tespit sistemleri Selenium ile yapılan otomasyonları kısıtlayabiliyor. Aldığınız hata mesajını ve hangi aşamada veri çekemediğini paylaşırsanız daha net bakabiliriz hocam..
    Şöyleki python ile başlatıp tarayıcısında giriş yapınca herhangi bir şirkette çalışanların isim soyisimeri meslekleri lazım
    Normalde kayıt alması lazımken almıyor böyle bir hata alıyorum
  • 22-07-2026, 23:25:45
    #5
    loocas adlı üyeden alıntı: mesajı görüntüle
    Şöyleki python ile başlatıp tarayıcısında giriş yapınca herhangi bir şirkette çalışanların isim soyisimeri meslekleri lazım
    Normalde kayıt alması lazımken almıyor böyle bir hata alıyorum
    Hocam bence sorun giriş kısmında değilde veri çekme tarafında LinkedIn’in çalışan listesi için kullanılan selectorlar güncel olmayabilir veya sayfa geç yüklendiği için Selenium elementleri bulamıyor olabilir. Hata çıktısı önemli yani bu konuda onu yapay zekaya falan atıp cevap aramayı deneyebilirsin hata çıktısını görneden yorumlamak pek doğru gelmiyor
  • 22-07-2026, 23:27:04
    #6
    0dan isteğinize göre şekillendirip size teslim edebiliriz. profilimde WhatsApp mevcuttur
  • 22-07-2026, 23:28:05
    #7
    https://github.com/joeyism/linkedin_scraper
    Buna baktınızmı hocam ?
  • 22-07-2026, 23:30:27
    #8
    Extsoft adlı üyeden alıntı: mesajı görüntüle
    https://github.com/joeyism/linkedin_scraper
    Buna baktınızmı hocam ?
    Bakamadım hocam
  • 22-07-2026, 23:34:36
    #9
    loocas adlı üyeden alıntı: mesajı görüntüle
    Bakamadım hocam
    Bi inceleyin derim hocam güncel bir repo ve baya iş görüyor