def main(): # Colorama module's initialization. init(autoreset=True) with open('COPYRIGHT', 'r', encoding="utf8") as copyright: cop = copyright.read() version_snoop = f"%(prog)s: {__version__}\n" + \ f"{requests.__description__}: {requests.__version__}\n" + \ f"Python: {platform.python_version()}\n\n" + \ f"\033[37m{cop}\033[0m\n" with open('sites.md', 'r', encoding="utf8") as support: sup = support.read() sup_color = f"\033[37m{sup}\033[0m" donate = (""" ╭donate: ├──BTC_BHC: \033[37m1EXoQj1rd5oi54k9yynVLsR4kG61e4s8g3\033[0m ├──Яндекс.Деньги: \033[37m4100111364257544\033[0m └──PayPal: \033[[email protected]\033[0m \nИсходный код: \033[37mhttps://github.com/snooppr/snoop\033[0m """ ) parser = ArgumentParser( formatter_class=RawDescriptionHelpFormatter, description=f"{module_name} (Version {__version__})", epilog=donate) parser.add_argument("--donate Y", action="store_true", dest="donation", help="Пожертвовать на развитие Snoop project-а") parser.add_argument( "--sort Y", action="store_true", dest="sort", help= "Обновление/сортировка черного и белого списков (.json) сайтов БД Snoop" ) parser.add_argument( "--version", "-V", action="version", version=(version_snoop), help="Вывод на дисплей: версий Snoop, Python; Сублицензии") parser.add_argument( "--verbose", "-v", "-d", "--debug", action="store_true", dest="verbose", default=False, help= "Вывод на дисплей отладочной информации и подробная её вербализация") # parser.add_argument("--rank", "-r", # action="store_true", dest="rank", default=False, # help="Результаты поиска сортируются не по алфавиту, а по полуярности рейтинга Alexa #опция временно отключена") parser.add_argument( "--folderoutput", "-fo", dest="folderoutput", help= "Указать каталог отличный от стандартного, куда будут сохранены результаты поиска при разовом поиске нескольких имён" ) parser.add_argument( "--output", "-o", dest="output", help= "Указать отличный от стандартного файл с сохранением результатов. По умолчанию файл для сохранения результатов — переменное username.txt" ) parser.add_argument( "--tor", "-t", action="store_true", dest="tor", default=False, help= "Делать запросы через Tor-службу; требуется чтобы Tor был установлен по системному стандартному пути и не модифицирован torrc" ) parser.add_argument( "--unique-tor", "-u", action="store_true", dest="unique_tor", default=False, help= "Делать запросы через Tor-службу с новой цепочкой Tor после каждого запроса; увеличивает время выполнения; требуется чтобы Tor был установлен по системному стандартному пути" ) parser.add_argument( "--proxy", "-p", metavar='PROXY_URL', action="store", dest="proxy", default=None, help="Делать запросы через прокси, например, socks5://127.0.0.1:9070") parser.add_argument( "--proxy_list", "-pl", metavar='PROXY_LIST', action="store", dest="proxy_list", default=None, help= "Поиск 'username' через случайный прокси, указать file.csv с прокси") parser.add_argument( "--check_proxies", "-cp", metavar='CHECK_PROXY', action="store", dest="check_prox", default=None, help="Связка с параметром '--proxy_list'. " "Скрипт проверяет рабочие ли предоставленные прокси из file.csv, являются ли они анонимными. " "Установите '0' для безлимитного количества успешно-проверенных прокси, установите > '1' для ограничения" ) parser.add_argument( "--csv", action="store_true", dest="csv", default=False, help="Сохранить файл в формате (nickname.CSV) с расширенным анализом") parser.add_argument( "--json", "-j", metavar="JSON_FILE", dest="json_file", default="data.json", help= "Указать для поиска 'username' другую БД сайтов в формате file.json") parser.add_argument( "--site", action="append", metavar='SITE_NAME', dest="site_list", default=None, help= "Указать имя сайта из БД (data.json). Ограничение поиска 'username' до одного ресурса" ) parser.add_argument( "--timeout", action="store", metavar='--time 9', dest="timeout", type=timeout_check, default=None, help="Выделение макс.времени на ожидание ответа от сервера\n" "Влияет на продолжительность поиска. Оптимальное значение при хорошем интернет соединении и нескольких 'упавших' сайтов = 9с." ) parser.add_argument("--print-found", action="store_true", dest="print_found_only", default=False, help="Выводить на печать только найденные аккаунты") parser.add_argument( "--no-color", action="store_true", dest="no_color", default=False, help="Монохромный терминал, не использовать цвета в url") parser.add_argument( "username", nargs='+', metavar='USERNAMES', action="store", help= "Никнейм разыскиваемого пользователя, поддерживается несколько имён") parser.add_argument("--list all", action="store_true", dest="listing", help="Вывод на дисплей БД поддерживаемых сайтов") parser.add_argument("--update Y", action="store_true", dest="update", help="Обновить Snoop") args = parser.parse_args() if args.sort: subprocess.run(["python3", "site_list.py"]) exit(0) if args.listing: listall = [] with open('sites.md') as listyes: for site in listyes.readlines(): patch = (site.split(']')[0]).replace("[", " ") listall.append(patch) print(Fore.GREEN + "++Белый список++", *listall, sep="\n") if args.listing: listall_bad = [] with open('bad_site.md') as listbad: for site_bad in listbad.readlines(): patch_bad = (site_bad.split(']')[0]).replace("[", " ") listall_bad.append(patch_bad) print(Fore.RED + "\n\n--Чёрный список--", *listall_bad, sep="\n") sys.exit(0) if args.donation: print(donate) webbrowser.open("https://yasobe.ru/na/snoop_project") print("Выход") sys.exit(0) if args.update: print("=======================") update_snoop() print("=======================\nВыход") sys.exit(0) # Argument check # TODO regex check on args.proxy if args.tor and (args.proxy != None or args.proxy_list != None): raise Exception("Tor и Proxy не могут быть запущены одновременно.") # Proxy argument check. # Does not necessarily need to throw an error, # since we could join the single proxy with the ones generated from the .csv, # but it seems unnecessarily complex at this time. if args.proxy != None and args.proxy_list != None: raise Exception( "Один прокси не может использоваться вместе со списком прокси.") # Make prompts if args.proxy != None: print("Using the proxy: " + args.proxy) global proxy_list if args.proxy_list != None: print_info("Loading proxies from", args.proxy_list, not args.color) proxy_list = load_proxies_from_csv(args.proxy_list) # Checking if proxies should be checked for anonymity. if args.check_prox != None and args.proxy_list != None: try: limit = int(args.check_prox) if limit == 0: proxy_list = check_proxy_list(proxy_list) elif limit > 0: proxy_list = check_proxy_list(proxy_list, limit) else: raise ValueError except ValueError: raise Exception( "Parameter --check_proxies/-cp must be a positive integer.") if args.tor or args.unique_tor: print( "\033[31mВнимание запущена экспериментальная функция! 'Snoop попытается работать через луковую сеть Tor'.\nВаши запросы могут посылаться НЕ анонимно!\033[0m\nТакже многие сайты могут блокировать выходные_ноды_Tor, что приведёт к 'ошибкам соединения' на этих сайтах." ) # Check if both output methods are entered as input. if args.output is not None and args.folderoutput is not None: print("Вы можете использовать только один метода выхода.") sys.exit(1) # Check validity for single username output. if args.output is not None and len(args.username) != 1: print("Вы можете использовать флаг --output только с одним username") sys.exit(1) response_json_online = None site_data_all = None # Try to load json from website. try: response_json_online = requests.get(url=args.json_file) except requests.exceptions.MissingSchema: # In case the schema is wrong it's because it may not be a website pass # Check if the response is appropriate. if response_json_online is not None and response_json_online.status_code == 200: # Since we got data from a website, try to load json and exit if parsing fails. try: site_data_all = response_json_online.json() except ValueError: print("Invalid JSON website!") sys.exit(1) pass data_file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), args.json_file) # This will be none if the request had a missing schema if site_data_all is None: # Check if the file exists otherwise exit. if not os.path.exists(data_file_path): print("JSON file не существует.") print( "Вы не добавили .json файл или убедитесь, что сделали запрос http:// или https://..." ) sys.exit(1) else: raw = open(data_file_path, "r", encoding="utf-8") try: site_data_all = json.load(raw) except: print("Invalid загружаемый JSON file.") if args.site_list is None: # Not desired to look at a sub-set of sites site_data = site_data_all else: # User desires to selectively run queries on a sub-set of the site list. # Make sure that the sites are supported & build up pruned site database. site_data = {} site_missing = [] for site in args.site_list: for existing_site in site_data_all: if site.lower() == existing_site.lower(): site_data[existing_site] = site_data_all[existing_site] if not site_data: # Build up list of sites not supported for future error message. site_missing.append(f"'{site}'") if site_missing: print( f"Ошибка: желаемые сайты не найдены: {', '.join(site_missing)}." ) sys.exit(1) #rak опция временно отключена #if args.rank: # Sort data by rank #site_dataCpy = dict(site_data) #ranked_sites = sorted(site_data, key=lambda k: ("rank" not in k, site_data[k].get("rank", sys.maxsize))) #site_data = {} #for site in ranked_sites: #site_data[site] = site_dataCpy.get(site) # Run report on all specified users. for username in args.username: print() if args.output: file = open(args.output, "w", encoding="utf-8") elif args.folderoutput: # In case we handle multiple usernames at a targetted folder. # If the folder doesnt exist, create it first if not os.path.isdir(args.folderoutput): os.mkdir(args.folderoutput) file = open(os.path.join(args.folderoutput, username + ".txt"), "w", encoding="utf-8") else: file = open(username + ".txt", "w", encoding="utf-8") # We try to ad a random member of the 'proxy_list' var as the proxy of the request. # If we can't access the list or it is empty, we proceed with args.proxy as the proxy. try: random_proxy = random.choice(proxy_list) proxy = f'{random_proxy.protocol}://{random_proxy.ip}:{random_proxy.port}' except (NameError, IndexError): proxy = args.proxy results = snoop(username, site_data, verbose=args.verbose, tor=args.tor, unique_tor=args.unique_tor, proxy=args.proxy, print_found_only=args.print_found_only, timeout=args.timeout, color=not args.no_color) exists_counter = 0 for website_name in results: dictionary = results[website_name] if dictionary.get("exists") == "yes": exists_counter += 1 file.write(dictionary["url_user"] + "\n") file.write("\n" f"Запрашиваемый объект: <") file.write(username) file.write(f"> найден: {exists_counter} раз(а)") file.write("\n" f"Обновлено: ") file.write(date.strftime("%d/%m/%Yг. в %Hч.%Mм.%Sс.")) print(Fore.WHITE + "├─Результаты поиска:", "всего найдено —", exists_counter, "url") file.close() if args.csv == True: with open(username + ".csv", "w", newline='', encoding="utf-8") as csv_report: writer = csv.writer(csv_report) writer.writerow([ 'username', 'name', 'url_main', 'url_user', 'exists', 'http_status', 'response_time_ms' ]) for site in results: writer.writerow([ username, site, results[site]['url_main'], results[site]['url_user'], results[site]['exists'], results[site]['http_status'], results[site]['response_time_ms'] ])
def main(): # Colorama module's initialization. init(autoreset=True) version_string = f"%(prog)s {__version__}\n" + \ f"{requests.__description__}: {requests.__version__}\n" + \ f"Python: {platform.python_version()}" parser = ArgumentParser( formatter_class=RawDescriptionHelpFormatter, description=f"{module_name} (Version {__version__})") parser.add_argument("--version", action="version", version=version_string, help="Display version information and dependencies.") parser.add_argument( "--verbose", "-v", "-d", "--debug", action="store_true", dest="verbose", default=False, help="Display extra debugging information and metrics.") parser.add_argument( "--rank", "-r", action="store_true", dest="rank", default=False, help= "Present websites ordered by their Alexa.com global rank in popularity." ) parser.add_argument( "--folderoutput", "-fo", dest="folderoutput", help= "If using multiple usernames, the output of the results will be saved to this folder." ) parser.add_argument( "--output", "-o", dest="output", help= "If using single username, the output of the result will be saved to this file." ) parser.add_argument( "--tor", "-t", action="store_true", dest="tor", default=False, help= "Make requests over Tor; increases runtime; requires Tor to be installed and in system path." ) parser.add_argument( "--unique-tor", "-u", action="store_true", dest="unique_tor", default=False, help= "Make requests over Tor with new Tor circuit after each request; increases runtime; requires Tor to be installed and in system path." ) parser.add_argument("--csv", action="store_true", dest="csv", default=False, help="Create Comma-Separated Values (CSV) File.") parser.add_argument( "--site", action="append", metavar='SITE_NAME', dest="site_list", default=None, help= "Limit analysis to just the listed sites. Add multiple options to specify more than one site." ) parser.add_argument( "--proxy", "-p", metavar='PROXY_URL', action="store", dest="proxy", default=None, help="Make requests over a proxy. e.g. socks5://127.0.0.1:1080") parser.add_argument( "--json", "-j", metavar="JSON_FILE", dest="json_file", default="data.json", help="Load data from a JSON file or an online, valid, JSON file.") parser.add_argument( "--proxy_list", "-pl", metavar='PROXY_LIST', action="store", dest="proxy_list", default=None, help= "Make requests over a proxy randomly chosen from a list generated from a .csv file." ) parser.add_argument( "--check_proxies", "-cp", metavar='CHECK_PROXY', action="store", dest="check_prox", default=None, help="To be used with the '--proxy_list' parameter. " "The script will check if the proxies supplied in the .csv file are working and anonymous." "Put 0 for no limit on successfully checked proxies, or another number to institute a limit." ) parser.add_argument( "--print-found", action="store_true", dest="print_found_only", default=False, help="Do not output sites where the username was not found.") parser.add_argument( "username", nargs='+', metavar='USERNAMES', action="store", help="One or more usernames to check with social networks.") args = parser.parse_args() # Argument check # TODO regex check on args.proxy if args.tor and (args.proxy != None or args.proxy_list != None): raise Exception("Tor and Proxy cannot be set in the meantime.") # Proxy argument check. # Does not necessarily need to throw an error, # since we could join the single proxy with the ones generated from the .csv, # but it seems unnecessarily complex at this time. if args.proxy != None and args.proxy_list != None: raise Exception("A single proxy cannot be used along with proxy list.") # Make prompts if args.proxy != None: print("Using the proxy: " + args.proxy) global proxy_list if args.proxy_list != None: print_info("Loading proxies from", args.proxy_list) proxy_list = load_proxies_from_csv(args.proxy_list) # Checking if proxies should be checked for anonymity. if args.check_prox != None and args.proxy_list != None: try: limit = int(args.check_prox) if limit == 0: proxy_list = check_proxy_list(proxy_list) elif limit > 0: proxy_list = check_proxy_list(proxy_list, limit) else: raise ValueError except ValueError: raise Exception( "Parameter --check_proxies/-cp must be a positive integer.") if args.tor or args.unique_tor: print("Using Tor to make requests") print( "Warning: some websites might refuse connecting over Tor, so note that using this option might increase connection errors." ) # Check if both output methods are entered as input. if args.output is not None and args.folderoutput is not None: print("You can only use one of the output methods.") sys.exit(1) # Check validity for single username output. if args.output is not None and len(args.username) != 1: print("You can only use --output with a single username") sys.exit(1) response_json_online = None site_data_all = None # Try to load json from website. try: response_json_online = requests.get(url=args.json_file) except requests.exceptions.MissingSchema: # In case the schema is wrong it's because it may not be a website pass # Check if the response is appropriate. if response_json_online is not None and response_json_online.status_code == 200: # Since we got data from a website, try to load json and exit if parsing fails. try: site_data_all = response_json_online.json() except ValueError: print("Invalid JSON from website!") sys.exit(1) pass data_file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), args.json_file) # This will be none if the request had a missing schema if site_data_all is None: # Check if the file exists otherwise exit. if not os.path.exists(data_file_path): print("JSON file doesn't exist.") print( "If this is not a file but a website, make sure you have appended http:// or https://." ) sys.exit(1) else: raw = open(data_file_path, "r", encoding="utf-8") try: site_data_all = json.load(raw) except: print("Invalid JSON loaded from file.") if args.site_list is None: # Not desired to look at a sub-set of sites site_data = site_data_all else: # User desires to selectively run queries on a sub-set of the site list. # Make sure that the sites are supported & build up pruned site database. site_data = {} site_missing = [] for site in args.site_list: for existing_site in site_data_all: if site.lower() == existing_site.lower(): site_data[existing_site] = site_data_all[existing_site] if not site_data: # Build up list of sites not supported for future error message. site_missing.append(f"'{site}'") if site_missing: print( f"Error: Desired sites not found: {', '.join(site_missing)}.") sys.exit(1) if args.rank: # Sort data by rank site_dataCpy = dict(site_data) ranked_sites = sorted( site_data, key=lambda k: ("rank" not in k, site_data[k].get("rank", sys.maxsize))) site_data = {} for site in ranked_sites: site_data[site] = site_dataCpy.get(site) # Run report on all specified users. for username in args.username: print() if args.output: file = open(args.output, "w", encoding="utf-8") elif args.folderoutput: # In case we handle multiple usernames at a targetted folder. # If the folder doesnt exist, create it first if not os.path.isdir(args.folderoutput): os.mkdir(args.folderoutput) file = open(os.path.join(args.folderoutput, username + ".txt"), "w", encoding="utf-8") else: file = open(username + ".txt", "w", encoding="utf-8") # We try to ad a random member of the 'proxy_list' var as the proxy of the request. # If we can't access the list or it is empty, we proceed with args.proxy as the proxy. try: random_proxy = random.choice(proxy_list) proxy = f'{random_proxy.protocol}://{random_proxy.ip}:{random_proxy.port}' except (NameError, IndexError): proxy = args.proxy results = {} results = sherlock(username, site_data, verbose=args.verbose, tor=args.tor, unique_tor=args.unique_tor, proxy=args.proxy, print_found_only=args.print_found_only) exists_counter = 0 for website_name in results: dictionary = results[website_name] if dictionary.get("exists") == "yes": exists_counter += 1 file.write(dictionary["url_user"] + "\n") file.write("Total Websites : {}".format(exists_counter)) file.close() if args.csv == True: with open(username + ".csv", "w", newline='', encoding="utf-8") as csv_report: writer = csv.writer(csv_report) writer.writerow([ 'username', 'name', 'url_main', 'url_user', 'exists', 'http_status', 'response_time_ms' ]) for site in results: writer.writerow([ username, site, results[site]['url_main'], results[site]['url_user'], results[site]['exists'], results[site]['http_status'], results[site]['response_time_ms'] ])
def main(): with open('COPYRIGHT', 'r', encoding="utf8") as copyright: cop = copyright.read() version_snoop = f"%(prog)s: {__version__}\n" + \ f"{requests.__description__}: {requests.__version__}\n" + \ f"Python: {platform.python_version()}\n\n" + \ f"\033[37m{cop}\033[0m\n" with open('sites.md', 'r', encoding="utf8") as support: sup = support.read() sup_color = f"\033[37m{sup}\033[0m" # Пожертование. donate = (""" ╭donate: ├──BTC_BHC: \033[37m1EXoQj1rd5oi54k9yynVLsR4kG61e4s8g3\033[0m ├──Яндекс.Деньги: \033[37m4100111364257544\033[0m └──PayPal: \033[[email protected]\033[0m \nИсходный код: \033[37mhttps://github.com/snooppr/snoop\033[0m """) # Назначение опций Snoop. parser = ArgumentParser( formatter_class=RawDescriptionHelpFormatter, description=f"{module_name} (Version {__version__})", epilog=donate) parser.add_argument("--donate Y", action="store_true", dest="donation", help="Пожертвовать на развитие Snoop project-а") parser.add_argument( "--sort Y", action="store_true", dest="sort", help= "Обновление/сортировка черного и белого списков (.json) сайтов БД Snoop" ) parser.add_argument( "--version", "-V", action="version", version=(version_snoop), help="Вывод на дисплей: версий Snoop, Python; Сублицензии") parser.add_argument( "--verbose", "-v", "-d", "--debug", action="store_true", dest="verbose", default=False, help= "Вывод на дисплей отладочной информации и подробная её вербализация") parser.add_argument( "--folderoutput", "-fo", dest="folderoutput", help= "Указать каталог отличный от стандартного, куда будут сохранены результаты поиска при разовом поиске нескольких имён" ) parser.add_argument( "--output", "-o", dest="output", help= "Указать отличный от стандартного файл с сохранением результатов. По умолчанию файл для сохранения результатов — переменное username.txt" ) parser.add_argument( "--tor", "-t", action="store_true", dest="tor", default=False, help= "Делать запросы через Tor-службу; требуется чтобы Tor был установлен по системному стандартному пути и не модифицирован torrc" ) parser.add_argument( "--unique-tor", "-u", action="store_true", dest="unique_tor", default=False, help= "Делать запросы через Tor-службу с новой цепочкой Tor после каждого запроса; увеличивает время выполнения; требуется чтобы Tor был установлен по системному стандартному пути" ) parser.add_argument( "--proxy", "-p", metavar='PROXY_URL', action="store", dest="proxy", default=None, help="Делать запросы через прокси, например, socks5://127.0.0.1:9070") parser.add_argument( "--proxy_list", "-pl", metavar='PROXY_LIST', action="store", dest="proxy_list", default=None, help= "Поиск 'username' через случайный прокси, указать file.csv с прокси") parser.add_argument( "--check_proxies", "-cp", metavar='CHECK_PROXY', action="store", dest="check_prox", default=None, help="Связка с параметром '--proxy_list'. " "Скрипт проверяет рабочие ли предоставленные прокси из file.csv, являются ли они анонимными. " "Установите '0' для безлимитного количества успешно-проверенных прокси, установите > '1' для ограничения" ) parser.add_argument( "--csv", action="store_true", dest="csv", default=False, help="Сохранить файл в формате (nickname.CSV) с расширенным анализом") parser.add_argument( "--json", "-j", metavar="JSON_FILE", dest="json_file", default="data.json", help= "Указать для поиска 'username' другую БД сайтов в формате file.json") parser.add_argument( "--site", action="append", metavar='SITE_NAME', dest="site_list", default=None, help= "Указать имя сайта из БД (data.json). Ограничение поиска 'username' до одного ресурса" ) parser.add_argument( "--timeout", action="store", metavar='--time 9', dest="timeout", type=timeout_check, default=None, help="Выделение макс.времени на ожидание ответа от сервера\n" "Влияет на продолжительность поиска. Оптимальное значение при хорошем интернет соединении и нескольких 'упавших' сайтов = 9с." ) parser.add_argument("--print-found", action="store_true", dest="print_found_only", default=False, help="Выводить на печать только найденные аккаунты") parser.add_argument( "--no-func", "-n", action="store_true", dest="no_color", default=False, help="""✓Монохромный терминал, не использовать цвета в url\n ✓Отключить звук\n ✓Запретить открытие web browser-a""") parser.add_argument( "username", nargs='+', metavar='USERNAMES', action="store", help= "Никнейм разыскиваемого пользователя, поддерживается несколько имён") parser.add_argument( "--list all", action="store_true", dest="listing", help="Вывод на дисплей БД (БС+ЧС) поддерживаемых сайтов") parser.add_argument("--update Y", action="store_true", dest="update", help="Обновить Snoop") args = parser.parse_args() # Опция сортировки. if args.sort: if sys.platform == 'win32': subprocess.run(["python", "site_list.py"]) else: subprocess.run(["python3", "site_list.py"]) exit(0) if args.listing: listall = [] with open('sites.md', "r", encoding="utf8") as listyes: for site in listyes.readlines(): patch = (site.split(']')[0]).replace("[", " ") listall.append(patch) print(Fore.GREEN + "++Белый список++", *listall, sep="\n") if args.listing: listall_bad = [] with open('bad_site.md', "r", encoding="utf8") as listbad: for site_bad in listbad.readlines(): patch_bad = (site_bad.split(']')[0]).replace("[", " ") listall_bad.append(patch_bad) print(Fore.RED + "\n\n--Чёрный список--", *listall_bad, sep="\n") sys.exit(0) # Опция донат. if args.donation: print(donate) webbrowser.open("https://yasobe.ru/na/snoop_project") print("Выход") sys.exit(0) # Завершение обновления Snoop. if args.update: print("=======================") update_snoop() print("=======================\nВыход") sys.exit(0) # Проверка остальных аргументов. # Проверка регулярных выражений TODO на args.proxy. if args.tor and (args.proxy != None or args.proxy_list != None): raise Exception("Tor и Proxy не могут быть запущены одновременно.") # Проверка аргументов прокси. # Не обязательно генерировать ошибку, так как мы могли бы объединить один прокси с теми, которые были сгенерированы из .csv, # но в настоящее время это кажется излишне сложным. if args.proxy != None and args.proxy_list != None: raise Exception( "Один прокси не может использоваться вместе со списком прокси.") # Делать подсказку. if args.proxy != None: print("Using the proxy: " + args.proxy) global proxy_list if args.proxy_list != None: print_info("Loading proxies from", args.proxy_list, not args.color) proxy_list = load_proxies_from_csv(args.proxy_list) # Анонимность? Должны ли проки проверяться на анонимность. if args.check_prox != None and args.proxy_list != None: try: limit = int(args.check_prox) if limit == 0: proxy_list = check_proxy_list(proxy_list) elif limit > 0: proxy_list = check_proxy_list(proxy_list, limit) else: raise ValueError except ValueError: raise Exception( "Parameter --check_proxies/-cp must be a positive integer.") if args.tor or args.unique_tor: print( Fore.RED + "Внимание запущена экспериментальная функция!'Snoop попытается работать через луковую сеть Tor'.\n\ Ваши запросы могут посылаться НЕ анонимно!\n\ Также многие сайты могут блокировать выходные_ноды_Tor, что приведёт к 'ошибкам соединения' на этих сайтах." ) # Проверка, введены ли оба метода вывода в качестве ввода. if args.output is not None and args.folderoutput is not None: print("Вы можете использовать только один метода выхода.") sys.exit(1) # Проверка правильность вывода одного из имен username. if args.output is not None and len(args.username) != 1: print("Вы можете использовать данный флаг только с одним username") sys.exit(1) response_json_online = None site_data_all = None # Попробовать загрузить JSON с веб-сайта. try: response_json_online = requests.get(url=args.json_file) except requests.exceptions.MissingSchema: # В случае если Shema неверная (не может быть на сайте). pass # Проверка на соответствие ответа. if response_json_online is not None and response_json_online.status_code == 200: # Поскольку мы получили данные с веб-сайта, попробовать загрузить json и выйти, если синтаксический анализ завершился ошибкой. try: site_data_all = response_json_online.json() except ValueError: print("Invalid JSON website!") sys.exit(1) pass data_file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), args.json_file) # Этого не будет, если в запросе отсутствовала Shema. if site_data_all is None: # Проверьте, существует ли файл, иначе выход. if not os.path.exists(data_file_path): print("JSON file не существует.") print( "Вы не добавили .json файл или убедитесь, что сделали запрос http:// или https://..." ) sys.exit(1) else: raw = open(data_file_path, "r", encoding="utf-8") try: site_data_all = json.load(raw) except: print("Invalid загружаемый JSON file.") if args.site_list is None: # Не желательно смотреть на подмножество сайтов. site_data = site_data_all else: # Пользователь желает выборочно запускать запросы к подмножеству списку сайтов. # Убедится, что сайты поддерживаются, создать сокращенную базу данных сайта. site_data = {} site_missing = [] for site in args.site_list: for existing_site in site_data_all: if site.lower() == existing_site.lower(): site_data[existing_site] = site_data_all[existing_site] if not site_data: # Создать список сайтов, которые не поддерживаются для будущего сообщения об ошибке. site_missing.append(f"'{site}'") if site_missing: print( f"Ошибка: желаемые сайты не найдены: {', '.join(site_missing)}." ) sys.exit(1) #Запись в txt. for username in args.username: print() if args.output: file = open(args.output, "w", encoding="utf-8") elif args.folderoutput: # В случае, если мы обрабатываем несколько имен пользователей в целевой папке. Если папка не существует, сначала создать её. if not os.path.isdir(args.folderoutput): os.mkdir(args.folderoutput) file = open(os.path.join(args.folderoutput, username + ".txt"), "w", encoding="utf-8") else: file = open("results/" + username + ".txt", "w", encoding="utf-8") try: file = open("results/" + username + ".txt", "w", encoding="utf-8") except (SyntaxError, ValueError): pass # Попытаться объявить случайный 'proxy_list' в качестве прокси запроса. # Если мы не можем получить доступ к списку или он пуст, мы используем 'args.proxy' в качестве прокси. try: random_proxy = random.choice(proxy_list) proxy = f'{random_proxy.protocol}://{random_proxy.ip}:{random_proxy.port}' except (NameError, IndexError): proxy = args.proxy results = snoop(username, site_data, verbose=args.verbose, tor=args.tor, unique_tor=args.unique_tor, proxy=args.proxy, print_found_only=args.print_found_only, timeout=args.timeout, color=not args.no_color) exists_counter = 0 file.write("Адрес | ресурс" + "\n\n") for website_name in results: dictionary = results[website_name] if dictionary.get("exists") == "yes": exists_counter += 1 file.write(dictionary["url_user"] + " | " + (website_name) + "\n") file.write("\n" f"Запрашиваемый объект: <") file.write(username) file.write(f"> найден: {exists_counter} раз(а)") file.write("\n" f"Обновлено: ") file.write(date.strftime("%d/%m/%Yг. в %Hч.%Mм.%Sс.")) print(Fore.WHITE + "├─Результаты поиска:", "всего найдено —", exists_counter, "url") #Запись в html. file = open("results/" + username + ".html", "w", encoding="utf-8") file.write("<h3>" + "Snoop Project" + "</h3>" + "Объект" + " " + "<b>" + (username) + "</b>" + " " + "найден на нижеперечисленных" + "<b> " + str(exists_counter) + "</b> ресурсах: " + "<br><ol>") for website_name in results: dictionary = results[website_name] if dictionary.get("exists") == "yes": exists_counter += 1 file.write("<li>" + "<a href='" + dictionary["url_user"] + "'>" + (website_name) + "</a>" + "</li>") file.write(f"</ol> Запрашиваемый объект: <") file.write(username) file.write(f"> найден: <b>{exists_counter/2}</b> раз(а).") file.write("<br> Обновлено: ") file.write(date.strftime("%d/%m/%Yг. в %Hч.%Mм.%Sс.") + "<br>") file.write( "<br><a href='https://github.com/snooppr/snoop'>Snoop/Исходный код</a>" ) file.close() if args.csv == True: print( Fore.WHITE + "├───Положительные результаты поиска сохранены в:", username + ".txt" + " " + "и", username + ".html") print( Fore.WHITE + "├───Расширенный анализ по поиску:" + Fore.RED + "\033[5m <\033[0m" + Fore.GREEN + f"{username}" + Fore.RED + "\033[5m>\033[0m", "сохранён в", username + ".csv") else: print( Fore.WHITE + "├───Положительные результаты поиска сохранены в:", username + ".txt" + " " + "и", username + ".html") file.close() #Запись в csv. if args.csv == True: with open("results/" + username + ".csv", "w", newline='', encoding="utf-8") as csv_report: writer = csv.writer(csv_report) writer.writerow([ 'Объект', 'Ресурс', 'url_main', 'url_user', 'статус', 'статус_кода', 'время/мс' ]) for site in results: writer.writerow([ username, site, results[site]['url_main'], results[site]['url_user'], results[site]['exists'], results[site]['http_status'], results[site]['response_time_ms'] ]) # Открыть/нет браузер с результатами поиска. if args.no_color == False: if exists_counter >= 1: webbrowser.open( str("file://" + str(dirresults) + "/results/" + str(username) + ".html")) # Музыка. playsound('end.wav')