Merhaba,
Python kaynak kodu olarak ücretsiz paylaşıyorum. İsteyen exe derleyebilir. Nasıl kullanırım diye PM atanlara cevap verilmeyecektir.
Sıradaki ücretsiz yazılım için takipte kalın
import customtkinter as ctk
import threading
import queue
import os
import time
import urllib.parse
import requests
import re
from datetime import datetime
from playwright.sync_api import sync_playwright
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
def sanitize_filename(title, max_length=150):
title = re.sub(r'[\\/:*?"<>|]', '', title)
title = re.sub(r'\s+', ' ', title).strip()
return title[:max_length]
class ScholarPDFBot(ctk.CTk):
def __init__(self):
super().__init__()
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")
self.title("Akademik Makale Botu")
self.geometry("1000x700")
self.log_queue = queue.Queue()
self.is_running = False
self.create_widgets()
self.after(100, self.process_logs)
# ---------------- GUI ---------------- #
def create_widgets(self):
ctk.CTkLabel(
self,
text="Akademik Makale Botu",
font=ctk.CTkFont(size=22, weight="bold")
).pack(pady=15)
frame = ctk.CTkFrame(self)
frame.pack(fill="x", padx=20)
ctk.CTkLabel(frame, text="Anahtar Kelime").grid(row=0, column=0, padx=5, pady=10, sticky="w")
self.keyword_entry = ctk.CTkEntry(frame, width=400)
self.keyword_entry.grid(row=0, column=1, padx=5)
ctk.CTkLabel(frame, text="Sayfa Sayısı").grid(row=1, column=0, padx=5, pady=10, sticky="w")
self.page_entry = ctk.CTkEntry(frame, width=100)
self.page_entry.insert(0, "3")
self.page_entry.grid(row=1, column=1, padx=5, sticky="w")
ctk.CTkLabel(frame, text="İndirme Klasörü").grid(row=2, column=0, padx=5, pady=10, sticky="w")
self.folder_entry = ctk.CTkEntry(frame, width=400)
self.folder_entry.insert(0, "pdfler")
self.folder_entry.grid(row=2, column=1, padx=5)
self.start_btn = ctk.CTkButton(self, text="Botu Başlat", command=self.start_bot)
self.start_btn.pack(pady=10)
self.log_box = ctk.CTkTextbox(self, height=400)
self.log_box.pack(fill="both", expand=True, padx=20, pady=10)
def log(self, msg):
timestamp = datetime.now().strftime("%H:%M:%S")
self.log_queue.put(f"[{timestamp}] {msg}")
def process_logs(self):
while not self.log_queue.empty():
self.log_box.insert("end", self.log_queue.get() + "\n")
self.log_box.see("end")
self.after(100, self.process_logs)
# ---------------- BOT ---------------- #
def start_bot(self):
if self.is_running:
return
keyword = self.keyword_entry.get().strip()
pages = int(self.page_entry.get())
folder = self.folder_entry.get().strip()
if not keyword:
self.log("❌ Anahtar kelime boş")
return
os.makedirs(folder, exist_ok=True)
self.is_running = True
self.start_btn.configure(state="disabled")
threading.Thread(
target=self.run_bot,
args=(keyword, pages, folder),
daemon=True
).start()
def run_bot(self, keyword, pages, folder):
encoded_kw = urllib.parse.quote(keyword)
self.log("🚀 Bot başlatıldı")
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(user_agent=USER_AGENT)
page = context.new_page()
total_downloaded = 0
for page_index in range(pages):
start = page_index * 10
url = f"https://scholar.google.com/scholar?start={start}&q={encoded_kw}&hl=tr&as_sdt=0,5"
self.log(f"🔍 Derinlemesine araştırılıyor... {page_index + 1}")
page.goto(url, timeout=60000)
page.wait_for_timeout(2000)
results = page.query_selector_all("div.gs_r")
for result in results:
title_text = "makale"
title_el = result.query_selector("h3.gs_rt")
if title_el:
title_text = title_el.inner_text()
safe_title = sanitize_filename(title_text)
pdf_urls = []
# SOL [PDF]
left_pdf = result.query_selector(".gs_or_ggsm a")
if left_pdf:
href = left_pdf.get_attribute("href")
if href:
pdf_urls.append(href)
# MAKALE İÇİ PDF
if not pdf_urls:
title_link = result.query_selector("h3.gs_rt a")
if title_link:
article_url = title_link.get_attribute("href")
if article_url:
try:
tmp = context.new_page()
tmp.goto(article_url, timeout=30000)
tmp.wait_for_timeout(2000)
links = tmp.query_selector_all("a[href]")
for l in links:
href = l.get_attribute("href")
if href and ".pdf" in href.lower():
pdf_urls.append(href)
break
tmp.close()
except:
pass
for pdf_url in pdf_urls:
filename = f"{safe_title}.pdf"
path = os.path.join(folder, filename)
if os.path.exists(path):
self.log(f"⏩ Zaten var: {filename}")
continue
try:
self.log(f"⬇️ Makale indiriliyor: {filename}")
self.download_pdf(pdf_url, path)
total_downloaded += 1
self.log("✅ Kaydedildi")
except Exception as e:
self.log(f"❌ İndirme hatası: {e}")
time.sleep(1)
browser.close()
self.log(f"🎉 Tamamlandı – Toplam PDF: {total_downloaded}")
self.start_btn.configure(state="normal")
self.is_running = False
def download_pdf(self, url, path):
headers = {
"User-Agent": USER_AGENT,
"Referer": "https://scholar.google.com/"
}
r = requests.get(url, headers=headers, timeout=40, allow_redirects=True)
r.raise_for_status()
content_type = r.headers.get("Content-Type", "").lower()
if not ("pdf" in content_type or "octet-stream" in content_type or url.lower().endswith(".pdf")):
raise Exception("PDF değil")
with open(path, "wb") as f:
f.write(r.content)
if __name__ == "__main__":
app = ScholarPDFBot()
app.mainloop()