Geçen yıl yaptığım arşivde kalanlardan bir araç. Kaynak kodları altta. Güle güle kullanın.

import customtkinter as ctk
from tkinter import filedialog, messagebox
import requests
from bs4 import BeautifulSoup
import threading
import socket
import time

ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")

class ProxyApp(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("Proxy Scraper & Tester")
        self.geometry("800x600")
        self.resizable(False, False)

        self.proxies = []
        self.valid_proxies = []

        self.tabview = ctk.CTkTabview(self, width=680, height=460)
        self.tabview.pack(pady=10, padx=10)
        self.tabview.add("Kazıma")
        self.tabview.add("Test")


        self.scrape_frame = self.tabview.tab("Kazıma")
        self.scrape_btn = ctk.CTkButton(self.scrape_frame, text="Proxy Kazı", command=self.start_scrape, corner_radius=12)
        self.scrape_btn.pack(pady=(20,10))

        self.scrape_result = ctk.CTkTextbox(self.scrape_frame, width=650, height=330, corner_radius=12)
        self.scrape_result.pack(padx=10)

        self.scrape_status = ctk.CTkLabel(self.scrape_frame, text="Hazır.", anchor="w")
        self.scrape_status.pack(fill="x", padx=10, pady=5)


        self.test_frame = self.tabview.tab("Test")

        self.test_btn = ctk.CTkButton(self.test_frame, text="Proxy Test Et", command=self.start_test, corner_radius=12)
        self.test_btn.pack(pady=(20,10))

        self.test_result = ctk.CTkTextbox(self.test_frame, width=650, height=330, corner_radius=12)
        self.test_result.pack(padx=10)

        self.test_status = ctk.CTkLabel(self.test_frame, text="Hazır.", anchor="w")
        self.test_status.pack(fill="x", padx=10, pady=5)


        self.export_btn = ctk.CTkButton(self.test_frame, text="Dışa Aktar", command=self.export_proxies, corner_radius=12)
        self.export_btn.pack(pady=(10,20))

    def start_scrape(self):
        self.scrape_btn.configure(state="disabled")
        self.scrape_status.configure(text="Proxy kazınıyor, lütfen bekleyiniz...")
        self.scrape_result.delete("0.0", "end")
        self.proxies.clear()
        threading.Thread(target=self.scrape_proxies).start()

    def scrape_proxies(self):
        sources = [
            self.scrape_proxyscrape,
            self.scrape_geonode,
            self.scrape_openproxy,
            self.scrape_hidemy_name,
            self.scrape_proxy_daily,
            self.scrape_proxy_nova,
            self.scrape_us_proxy
        ]
        proxies_set = set()
        for source in sources:
            try:
                new_proxies = source()
                proxies_set.update(new_proxies)
            except Exception as e:
                print(f"{source.__name__} hatası: {e}")

        self.proxies = list(proxies_set)

        self.scrape_result.delete("0.0", "end")
        for p in self.proxies:
            self.scrape_result.insert("end", p + "\n")

        self.scrape_status.configure(text=f"Toplam {len(self.proxies)} proxy bulundu.")
        self.scrape_btn.configure(state="normal")

    
    def scrape_proxyscrape(self):
        url = "https://api.proxyscrape.com/v2/?request=getproxies&protocol=http&timeout=10000&country=all&ssl=all&anonymity=all"
        res = requests.get(url, timeout=10)
        proxies = res.text.strip().split('\n')
        return [p.strip() for p in proxies if p.strip()]

    def scrape_geonode(self):
        url = "https://geonode.com/free-proxy-list/"
        headers = {"User-Agent":"Mozilla/5.0"}
        res = requests.get(url, headers=headers, timeout=10)
        soup = BeautifulSoup(res.text, "html.parser")
        proxies = []
        table = soup.find("table")
        if not table:
            return proxies
        tbody = table.find("tbody")
        if not tbody:
            return proxies
        rows = tbody.find_all("tr")
        for row in rows:
            cols = row.find_all("td")
            if len(cols) < 2:
                continue
            ip = cols[0].text.strip()
            port = cols[1].text.strip()
            proxies.append(f"{ip}:{port}")
        return proxies

    def scrape_openproxy(self):
        url = "https://openproxy.space/list/http"
        headers = {"User-Agent":"Mozilla/5.0"}
        res = requests.get(url, headers=headers, timeout=10)
        soup = BeautifulSoup(res.text, "html.parser")
        proxies = []
        divs = soup.find_all("div", class_="proxy")
        for div in divs:
            text = div.text.strip()
            if ":" in text:
                proxies.append(text)
        return proxies

    def scrape_hidemy_name(self):
        base_url = "https://hidemy.name/en/proxy-list/?type=hs&start="
        headers = {
            "User-Agent": "Mozilla/5.0"
        }
        proxies = []
        for start in range(0, 320, 64):
            try:
                url = f"{base_url}{start}"
                res = requests.get(url, headers=headers, timeout=10)
                soup = BeautifulSoup(res.text, "html.parser")
                table = soup.find("table")
                if not table:
                    continue
                tbody = table.find("tbody")
                for row in tbody.find_all("tr"):
                    cols = row.find_all("td")
                    if len(cols) >= 2:
                        ip = cols[0].text.strip()
                        port = cols[1].text.strip()
                        proxies.append(f"{ip}:{port}")
            except Exception as e:
                print(f"Hata (sayfa {start}): {e}")
        return proxies

    def scrape_proxy_daily(self):
        url = "https://www.proxydaily.com/"
        res = requests.get(url, timeout=10)
        soup = BeautifulSoup(res.text, "html.parser")
        pre = soup.find("textarea", {"class": "form-control"})
        if not pre:
            return []
        return [line.strip() for line in pre.text.splitlines() if ":" in line]

    def scrape_proxy_nova(self):
        url = "https://www.proxynova.com/proxy-server-list/"
        res = requests.get(url, timeout=10)
        soup = BeautifulSoup(res.text, "html.parser")
        rows = soup.select("table tbody tr")
        proxies = []
        for row in rows:
            cols = row.find_all("td")
            if len(cols) >= 2:
                ip_script = cols[0].find("abbr") or cols[0]
                ip = ip_script.text.strip()
                port = cols[1].text.strip()
                if ip and port:
                    proxies.append(f"{ip}:{port}")
        return proxies

    def scrape_us_proxy(self):
        url = "https://www.us-proxy.org/"
        res = requests.get(url, timeout=10)
        soup = BeautifulSoup(res.text, "html.parser")
        rows = soup.select("table#proxylisttable tbody tr")
        proxies = []
        for row in rows:
            cols = row.find_all("td")
            if len(cols) >= 2:
                ip = cols[0].text.strip()
                port = cols[1].text.strip()
                proxies.append(f"{ip}:{port}")
        return proxies

    

    def start_test(self):
        if not self.proxies:
            messagebox.showwarning("Uyarı", "Önce proxy kazımalısınız.")
            return
        self.test_btn.configure(state="disabled")
        self.test_status.configure(text="Proxyler test ediliyor, lütfen bekleyiniz...")
        self.test_result.delete("0.0", "end")
        self.valid_proxies.clear()
        threading.Thread(target=self.test_proxies_thread).start()

    def test_proxies_thread(self):
        threads = []
        lock = threading.Lock()

        def test_proxy(proxy):
            try:
                ip, port = proxy.split(":")
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(3)
                result = sock.connect_ex((ip, int(port)))
                sock.close()
                if result == 0:
                    with lock:
                        self.valid_proxies.append(proxy)
                        self.test_result.insert("end", f"[BAŞARILI] {proxy}\n")
                else:
                    with lock:
                        self.test_result.insert("end", f"[BAŞARISIZ] {proxy}\n")
            except:
                with lock:
                    self.test_result.insert("end", f"[HATA] {proxy}\n")

        max_threads = 20
        for proxy in self.proxies:
            while threading.active_count() > max_threads:
                time.sleep(0.05)
            t = threading.Thread(target=test_proxy, args=(proxy,))
            t.start()
            threads.append(t)
        for t in threads:
            t.join()

        self.test_status.configure(text=f"Test tamamlandı. {len(self.valid_proxies)} başarılı proxy bulundu.")
        self.test_btn.configure(state="normal")

    def export_proxies(self):
        if not self.valid_proxies:
            messagebox.showwarning("Uyarı", "Dışa aktarılacak başarılı proxy yok.")
            return

        file_path = filedialog.asksaveasfilename(
            defaultextension=".txt",
            filetypes=[("Metin Dosyası", "*.txt")],
            title="Proxy dosyasını kaydet"
        )
        if not file_path:
            return

        try:
            with open(file_path, "w", encoding="utf-8") as f:
                for p in self.valid_proxies:
                    f.write(p + "\n")
            messagebox.showinfo("Başarılı", f"{len(self.valid_proxies)} proxy dosyaya kaydedildi.")
        except Exception as e:
            messagebox.showerror("Hata", f"Dosya kaydedilirken hata oluştu:\n{e}")

if __name__ == "__main__":
    app = ProxyApp()
    app.mainloop()