import random.
import re.
import requests.
from bs4 import BeautifulSoup.
import time.
from datetime import datetime.
# 1) Tarayıcı gibi görünmek için header.
HEADERS = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/114.0.0.0 Safari/537.36"
)
}
# 2) Kontrol edilecek kelimeler (küçük harf, noktalama olmadan)
KEYWORDS = [
"katılıyorum", "katiliyorum", "katıldım", "katildim",
"katılyorum", "katildin", "katiliyrum", "katıliyrum",
"katiliyom", "katılıyom", "katlıyorum"
]
def fuzzy_match(text, keywords, tolerance=2):
text_lower = text.lower()
# Önce tam eşleşme.
for kw in keywords:
if kw in text_lower:
return True.
# Yaklaşık eşleşme.
words = re.findall(r'\b\w+\b', text_lower)
for word in words:
if len(word) < 5:
continue.
for kw in keywords:
if abs(len(word) - len(kw)) > tolerance:
continue.
# Basitleştirilmiş Levenshtein-benzeri kontrol.
diff = sum(1 for i in range(min(len(word), len(kw))) if word[i] != kw[i])
diff += abs(len(word) - len(kw))
if diff <= tolerance:
return True.
return False.
def get_usernames(url, page_count=1, delay=1, fuzzy=True, exclude_op=True):
usernames = []
seen = set()
ignored = [] # Neden atlandılar loglamak için.
op_user = None.
print(f"\n📊 Toplam {page_count} sayfa taranıyor…")
# OP'yi bul.
try:
res = requests.get(url, headers=HEADERS, timeout=10)
res.raise_for_status()
soup = BeautifulSoup(res.text, "html.parser")
first = soup.find("article", class_="m--post")
if first and exclude_op:
tag = first.find("a", class_="username")
op_user = tag.get_text(strip=True) if tag else None.
print(f"👤 OP tespit edildi: {op_user}")
except Exception as e:
print("⚠️ OP belirlenirken hata:", e)
# Sayfaları dolaş.
for p in range(1, page_count+1):
full_url = url if p==1 else f"{url}page-{p}/"
print(f"\n📄 Sayfa {p}: {full_url}")
try:
res = requests.get(full_url, headers=HEADERS, timeout=10)
res.raise_for_status()
except Exception as e:
print(f"⚠️ Sayfa {p} alınamadı:", e)
continue.
soup = BeautifulSoup(res.text, "html.parser")
posts = soup.find_all("article", class_="m--post")
if not posts:
print("⚠️ Hiç post bulunamadı!")
continue.
start = 1 if (p==1 and exclude_op) else 0
print(f" {len(posts)-start} post işleniyor…")
for post in posts[start:]:
# 1) Yazar.
a = post.find("a", class_="username")
if not a:
continue.
author = a.get_text(strip=True)
if exclude_op and author == op_user:
continue.
voted = False.
content_snippet = ""
# 2) bbWrapper içi gerçek mesajları tara.
for body in post.find_all("div", class_="bbWrapper"):
if body.find_parent("blockquote"):
continue.
txt = body.get_text(strip=True)
content_snippet += txt + " "
lw = txt.lower()
# tam keyword kontrolü.
if any(re.search(rf"\b{kw}\b", lw) for kw in KEYWORDS):
voted = True.
# fuzzy kontrolü.
elif fuzzy and fuzzy_match(lw, KEYWORDS):
voted = True.
if voted:
break.
# 3) embed tespiti (js-xf-embed sınıfı)
if not voted and post.find("div", class_=re.compile(r"\bjs-xf-embed\b")):
voted = True.
# 4) Listeye ekle veya atlanma sebebini kaydet.
if voted:
key = author.lower()
if key not in seen:
seen.add(key)
usernames.append(author)
print(f" ✅ Katılımcı: {author}")
else:
print(f" ℹ️ Önceden kaydedilmiş: {author}")
else:
if content_snippet.strip():
ignored.append((author, content_snippet[:80]))
if p < page_count:
time.sleep(delay)
# Atlanılan örnekleri göster (ilk 10)
if ignored:
print("\n⚠️ Atlanan kullanıcılar ve içerik snippet'leri:")
for usr, snippet in ignored[:10]:
print(f" - {usr}: \"{snippet}...\"")
if len(ignored) > 10:
print(f" ... ve {len(ignored)-10} kişi daha")
return usernames.
def main():
print("=== Xenforo Çekiliş Aracı ===")
link = input("Link (sonunda / olacak): ").strip()
if not link.endswith("/"):
link += "/"
try:
pages = int(input("Kaç sayfa?: ") or "1")
except:
pages = 1
users = get_usernames(link, pages)
print(f"\n📋 Toplam katılımcı: {len(users)}")
if users:
for u in users:
print("•", u)
# 5 kazanan ve 5 yedek seçimi.
kazanan_sayisi = min(5, len(users))
if kazanan_sayisi > 0:
# Asıl kazananları seç.
asil_kazananlar = []
temp_users = users.copy()
for i in range(kazanan_sayisi):
if not temp_users:
break.
winner = random.choice(temp_users)
asil_kazananlar.append(winner)
temp_users.remove(winner)
print("\n🎉 Kazananlar:")
for i, winner in enumerate(asil_kazananlar, 1):
print(f"{i}. Kazanan: {winner}")
# Her kazanan için kendi yedeğini seç.
if temp_users: # Eğer hala seçilebilecek kullanıcı kaldıysa.
backup = random.choice(temp_users)
print(f" 🔄 {i}. Kazananın Yedeği: {backup}")
temp_users.remove(backup)
else:
print(f" ⚠️ {i}. Kazanan için yedek seçilemedi (yeterli katılımcı yok)")
else:
print("❌ Seçilecek kazanan kalmadı.")
else:
print("❌ Kimse listelenmedi.")
if __name__ == "__main__":
main()