Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import selenium, time, queue, threading, os, subprocess, sys, shutil, hashlib, datetime
- from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
- # Целевой URL, в нём должен присутствовать символ из MASK_SYMBOL -
- # на его место будут подставляться имена искомых объектов
- TARGET_URL = sys.argv[1]
- DICT = sys.argv[2]
- THREADS = int(sys.argv[3])
- MASK_SYMBOL = "№"
- # Сколько запросов делаем на один браузер (потом он уничтожается и создаётся заново).
- # Необходимо потому что при долгой работе c одним и тем же объектом браузера начинает глючить.
- ONE_BROWSER_QUERYS_LIMIT = 150
- # На сколько останавливаем работу если сработала защита от DDoS (подождите № секунд, сейчас вы будете перемещены)
- ANTI_DDOS_SLEEP_SECS = 10
- # ID элемента на странице-аналоге 404, по его наличию поймём что запрошенный объект не существует
- NOT_FOUND_ELEMENT_ID = "errorOverlay"
- # Настройки для профиля FF
- profile_settings = {'permissions.default.stylesheet': 2,
- 'permissions.default.image': 2,
- 'dom.ipc.plugins.enabled.libflashplayer.so': 'false',
- 'plugin.state.flash': 0}
- # Заполняем очередь паролями
- q = queue.Queue()
- for obj in open(DICT).readlines():
- q.put( obj.strip() )
- # Функция отображения секунд в человеческое время (дни, часы, минуты, секунды)
- def human_time(secs):
- result = ""
- if secs > 60*60*24:
- result += "{0}d ".format( int(secs/(60*60*24)) )
- secs = secs%(60*60*24)
- if secs > 60*60:
- result += "{0}h ".format( int(secs/(60*60)) )
- secs = secs%(60*60)
- if secs > 60:
- result += "{0}m ".format( int(secs/60) )
- secs = secs%60
- if secs:
- result += "{0}s ".format( secs )
- return result
- # Аналог прогресс-бара для консоли
- class Counter:
- counter = 0
- def __init__(self, point, newStr, all_count):
- self.point = point
- self.newStr = newStr
- self.all_count = all_count
- self.start_time = int(time.time())
- def up(self):
- self.counter += 1
- if self.counter%self.point == 0:
- print(".", end='')
- if self.counter%self.newStr == 0:
- percent = round(self.counter / (self.all_count / 100), 2)
- per_sec = round( self.counter / (int(time.time()) - self.start_time) )
- remaning = human_time( int((self.all_count-self.counter) / per_sec) )
- print("(Done {0} from {1} ({2}%), {3}p/s, {4} remaning)".format(self.counter, self.all_count, percent, per_sec, remaning))
- sys.stdout.flush()
- return self
- class Worker(threading.Thread):
- def __init__(self, q, num, counter, result):
- super().__init__()
- self.q = q
- self.num = num
- self.counter = counter
- self.browser_requests_counter = 0
- self.browser = None
- self.profile_dir = '/tmp/selenium-ff-profile-{0}'.format(self.num)# Путь к профилю FF текущего потока
- self.result = result
- time.sleep(num*2)
- # Метод получения браузера текущего потока
- def _get_browser(self):
- # Если достигли лимита в запросах на браузер - убиваем его и создаём заново
- if self.browser_requests_counter == ONE_BROWSER_QUERYS_LIMIT:
- self._kill_browser()
- self.browser_requests_counter = 0
- if not self.browser:
- self.browser = self._make_browser()
- self.browser_requests_counter += 1
- return self.browser
- def _kill_browser(self):
- if self.browser:
- self.browser.quit()
- del self.browser
- self.browser = None
- def _make_browser(self):
- if os.path.exists(self.profile_dir):
- shutil.rmtree(self.profile_dir)
- os.mkdir(self.profile_dir)
- try:
- firefoxProfile = FirefoxProfile(self.profile_dir)
- for setting in profile_settings:
- firefoxProfile.set_preference(setting, profile_settings[setting])
- browser = selenium.webdriver.Firefox(firefoxProfile)
- return browser
- except selenium.common.exceptions.WebDriverException:
- return self._make_browser()
- def _error_log(self, password, text, source):
- source_filename = hashlib.md5(str(datetime.datetime.now()).encode("utf")).hexdigest() + ".html"
- fh = open("errors/error.log", "a")
- fh.write("#{0: ^40}#\n".format( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
- fh.write("Obj: {0}\nError: {1}\nHTML: {2}".format(obj, text, source_filename))
- fh.write("#{0: ^40}#\n\n")
- fh.close()
- fh = open("errors/" + source_filename, "w")
- fh.write(source)
- fh.close()
- def run(self):
- while True:
- try:
- obj = self.q.get()
- self.counter.up()
- browser = self._get_browser()
- browser.get(TARGET_URL.replace(MASK_SYMBOL, obj))
- found = False
- # Первый признак существования элемента - отсутствие тега с id из NOT_FOUND_ELEMENT_ID
- try:
- browser.find_element_by_class_name(NOT_FOUND_ELEMENT_ID)
- except selenium.common.exceptions.NoSuchElementException:
- found = True
- # Если такого тега нет, ищем признак ошибки 404 от Nginx (.//body[@bgcolor='white']/center/h1)
- # а также текст 'No input file specified.'
- # Если и этого нет, значит объект существует
- if found \
- and not len( browser.find_elements_by_xpath(".//body[@bgcolor='white']/center/h1") ) \
- and browser.find_elements_by_xpath(".//html/body")[0].text != 'No input file specified.':
- self.result.append(TARGET_URL.replace(MASK_SYMBOL, obj))
- except queue.Empty:
- self._kill_browser()
- break
- except BaseException as e:
- try:
- page_source = browser.page_source
- except BaseException:
- page_source = "NONE"
- print("E", end="")
- self._error_log(obj, str(e), page_source)
- self.q.put(obj)
- finally:
- self.q.task_done()
- self._kill_browser()
- print("#{0: ^40}#".format( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
- counter = Counter(50, 500, q.qsize())
- result = []
- for i in range(THREADS):
- w = Worker(q, i, counter, result)
- w.daemon = True
- w.start()
- q.join()
- print("")
- print("\n".join(result))
- print("#{0: ^40}#".format( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement