Advertisement
Guest User

selenium-dafs.py

a guest
Aug 4th, 2014
748
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.45 KB | None | 0 0
  1. import selenium, time, queue, threading, os, subprocess, sys, shutil, hashlib, datetime
  2. from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
  3.  
  4. # Целевой URL, в нём должен присутствовать символ из MASK_SYMBOL -
  5. # на его место будут подставляться имена искомых объектов
  6. TARGET_URL = sys.argv[1]
  7. DICT = sys.argv[2]
  8. THREADS = int(sys.argv[3])
  9.  
  10. MASK_SYMBOL = "№"
  11.  
  12. # Сколько запросов делаем на один браузер (потом он уничтожается и создаётся заново).
  13. # Необходимо потому что при долгой работе c одним и тем же объектом браузера начинает глючить.
  14. ONE_BROWSER_QUERYS_LIMIT = 150
  15. # На сколько останавливаем работу если сработала защита от DDoS (подождите № секунд, сейчас вы будете перемещены)
  16. ANTI_DDOS_SLEEP_SECS = 10
  17.  
  18. # ID элемента на странице-аналоге 404, по его наличию поймём что запрошенный объект не существует
  19. NOT_FOUND_ELEMENT_ID = "errorOverlay"
  20.  
  21. # Настройки для профиля FF
  22. profile_settings = {'permissions.default.stylesheet': 2,
  23.                     'permissions.default.image': 2,
  24.                     'dom.ipc.plugins.enabled.libflashplayer.so': 'false',
  25.                     'plugin.state.flash': 0}
  26.  
  27. # Заполняем очередь паролями
  28. q = queue.Queue()
  29. for obj in open(DICT).readlines():
  30.     q.put( obj.strip() )
  31.  
  32. # Функция отображения секунд в человеческое время (дни, часы, минуты, секунды)
  33. def human_time(secs):
  34.     result = ""
  35.     if secs > 60*60*24:
  36.         result += "{0}d ".format( int(secs/(60*60*24)) )
  37.         secs = secs%(60*60*24)
  38.     if secs > 60*60:
  39.         result += "{0}h ".format( int(secs/(60*60)) )
  40.         secs = secs%(60*60)
  41.     if secs > 60:
  42.         result += "{0}m ".format( int(secs/60) )
  43.         secs = secs%60
  44.     if secs:
  45.         result += "{0}s ".format( secs )
  46.     return result
  47.  
  48. # Аналог прогресс-бара для консоли
  49. class Counter:
  50.     counter = 0
  51.  
  52.     def __init__(self, point, newStr, all_count):
  53.         self.point = point
  54.         self.newStr = newStr
  55.         self.all_count = all_count
  56.         self.start_time = int(time.time())
  57.  
  58.     def up(self):
  59.         self.counter += 1
  60.  
  61.         if self.counter%self.point == 0:
  62.             print(".", end='')
  63.         if self.counter%self.newStr == 0:
  64.             percent = round(self.counter / (self.all_count / 100), 2)
  65.             per_sec = round( self.counter / (int(time.time()) - self.start_time) )
  66.             remaning = human_time( int((self.all_count-self.counter) / per_sec) )
  67.             print("(Done {0} from {1} ({2}%), {3}p/s, {4} remaning)".format(self.counter, self.all_count, percent, per_sec, remaning))
  68.  
  69.         sys.stdout.flush()
  70.  
  71.         return self
  72.  
  73. class Worker(threading.Thread):
  74.     def __init__(self, q, num, counter, result):
  75.         super().__init__()
  76.  
  77.         self.q = q
  78.         self.num = num
  79.         self.counter = counter
  80.         self.browser_requests_counter = 0
  81.         self.browser = None
  82.         self.profile_dir = '/tmp/selenium-ff-profile-{0}'.format(self.num)# Путь к профилю FF текущего потока
  83.         self.result = result
  84.  
  85.         time.sleep(num*2)
  86.  
  87.     # Метод получения браузера текущего потока
  88.     def _get_browser(self):
  89.         # Если достигли лимита в запросах на браузер - убиваем его и создаём заново
  90.         if self.browser_requests_counter == ONE_BROWSER_QUERYS_LIMIT:
  91.             self._kill_browser()
  92.             self.browser_requests_counter = 0
  93.  
  94.         if not self.browser:
  95.             self.browser = self._make_browser()
  96.  
  97.         self.browser_requests_counter += 1
  98.  
  99.         return self.browser
  100.  
  101.     def _kill_browser(self):
  102.         if self.browser:
  103.             self.browser.quit()
  104.             del self.browser
  105.             self.browser = None
  106.  
  107.     def _make_browser(self):
  108.         if os.path.exists(self.profile_dir):
  109.             shutil.rmtree(self.profile_dir)
  110.         os.mkdir(self.profile_dir)
  111.  
  112.         try:
  113.             firefoxProfile = FirefoxProfile(self.profile_dir)
  114.             for setting in profile_settings:
  115.                 firefoxProfile.set_preference(setting, profile_settings[setting])
  116.             browser = selenium.webdriver.Firefox(firefoxProfile)
  117.             return browser
  118.         except selenium.common.exceptions.WebDriverException:
  119.             return self._make_browser()
  120.  
  121.     def _error_log(self, password, text, source):
  122.         source_filename = hashlib.md5(str(datetime.datetime.now()).encode("utf")).hexdigest() + ".html"
  123.  
  124.         fh = open("errors/error.log", "a")
  125.         fh.write("#{0: ^40}#\n".format( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
  126.         fh.write("Obj: {0}\nError: {1}\nHTML: {2}".format(obj, text, source_filename))
  127.         fh.write("#{0: ^40}#\n\n")
  128.         fh.close()
  129.  
  130.         fh = open("errors/" + source_filename, "w")
  131.         fh.write(source)
  132.         fh.close()
  133.  
  134.     def run(self):
  135.         while True:
  136.             try:
  137.                 obj = self.q.get()
  138.                 self.counter.up()
  139.  
  140.                 browser = self._get_browser()
  141.                 browser.get(TARGET_URL.replace(MASK_SYMBOL, obj))
  142.  
  143.                 found = False
  144.                 # Первый признак существования элемента - отсутствие тега с id из NOT_FOUND_ELEMENT_ID
  145.                 try:
  146.                     browser.find_element_by_class_name(NOT_FOUND_ELEMENT_ID)
  147.                 except selenium.common.exceptions.NoSuchElementException:
  148.                     found = True
  149.  
  150.                 # Если такого тега нет, ищем признак ошибки 404 от Nginx (.//body[@bgcolor='white']/center/h1)
  151.                 # а также текст 'No input file specified.'
  152.                 # Если и этого нет, значит объект существует
  153.                 if found \
  154.                     and not len( browser.find_elements_by_xpath(".//body[@bgcolor='white']/center/h1") ) \
  155.                     and browser.find_elements_by_xpath(".//html/body")[0].text != 'No input file specified.':
  156.                     self.result.append(TARGET_URL.replace(MASK_SYMBOL, obj))
  157.             except queue.Empty:
  158.                 self._kill_browser()
  159.                 break
  160.             except BaseException as e:
  161.                 try:
  162.                     page_source = browser.page_source
  163.                 except BaseException:
  164.                     page_source = "NONE"
  165.  
  166.                 print("E", end="")
  167.                 self._error_log(obj, str(e), page_source)
  168.                 self.q.put(obj)
  169.             finally:
  170.                 self.q.task_done()
  171.         self._kill_browser()
  172.  
  173.  
  174. print("#{0: ^40}#".format( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
  175.  
  176.  
  177. counter = Counter(50, 500, q.qsize())
  178. result = []
  179. for i in range(THREADS):
  180.     w = Worker(q, i, counter, result)
  181.     w.daemon = True
  182.     w.start()
  183.  
  184. q.join()
  185.  
  186. print("")
  187. print("\n".join(result))
  188.  
  189. print("#{0: ^40}#".format( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement