1. Python / Говнокод #25890

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    from xml.sax.saxutils import unescape
    
    HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36',
               'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
               'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
               'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3'}
    
    GOOGLE_RE = re.compile(r'<h3 class="r"><a href="([^"]+)" ')
    YANDEX_RE = re.compile(r'<span class="serp-url__mark">.</span><a class="link serp-url__link" target="_blank" href="([^"]+)"')
    PROXY_RE = re.compile(r'(\d+\.\d+\.\d+\.\d+)[:\s]+(\d+)')
    
    def search_google(requests_list, qdr=None, interval=2):
        res = []
        qdr = 'd' if qdr is None or not qdr in ['w', 'd'] else qdr
        REQ_FORMAT = 'https://www.google.com/search?q={0}&num=100&tbs=qdr:' + qdr
        i = 0
    
        for term in requests_list:
            req = REQ_FORMAT.format(term)
            response = requests.get(req, headers=HEADERS)
            if response.status_code != 200:
                print ('Google returned {0}'.format(response.status_code))
                time.sleep(interval)
                continue
    
            txt = response.text
            found = GOOGLE_RE.findall(txt)
            res += found
            print ('done term {0}, found {1} URLs'.format(i, len(found)))
            i += 1
    
            time.sleep(interval)
    
        map(unescape, res)
        
        return res

    Древняя граббилка открытых прокси при помощи поисковых систем. Когда-то даже работала.

    Запостил: gost, 01 Октября 2019

    Комментарии (29) RSS

    • print ()
      Не такая уж древняя
      Ответить
      • Я её высрал больше трёх лет назад; по меркам современного веба — вполне себе старость. А сам принцип сканирования новых списков проксей на основе старого вообще родом из эпохи образования гугла.
        Ответить
        • Лол. У меня проги на питоне с 10-12 года живут и даже работают.

          Кстати, можно настроить requests или другой клиент на то чтобы он кидал исключение при коде не 200? Это вполне ожидаемое поведение.
          Ответить
          • Ну это уже вообще времена до Большого Взрыва!

            Есть костыль в виде:
            response = requests.get('http://hui.com')
            response.raise_for_status()  # response.status_code == 200 => None; != 200 => requests.exceptions.HTTPError
            Ответить
            • До большого взрыва это перл года 2006.

              Хотелось бы даже без этого. Меня это устраивает как поведение по умолчанию. Вот в дотнете всё сделали правильно.
              Ответить
              • Тогда только манкипатчить, скорее всего.

                Честно говоря, не уверен, что безусловное выкидывание исключения на не-200 — правильно. Иногда возникают ситуации, когда надо, например, загрузить в том числе и 404-е/500-е страницы. Но вот то, что авторы «requests» не запилили флаг для подобного — цэ говно.

                UPD: https://github.com/psf/requests/issues/2152. Какой анскилл (((
                Ответить
                • Для таких случаев можно добавить параметр, но чаще исключение устраивает.

                  И что теперь делать? Писать свою обертку над requests и таскать ее с собой?
                  Ответить
              • Спасибо, иди нахуй.
                Ответить
      • Принт со скобочками и во втором петоне ра. Даже без __future__.
        Ответить
    • Да, и ты половину кода забыл.
      Ответить
      • Да там остальное — УГ в виде сворачивания-разворачивания списков.
        Ответить
    • map(unescape, res)

      Што?
      Ответить
      • Лол, и правда. Предполагалось, что это будет менять всякие там «&amp;» обратно на «&» во всех найденных ссылках. В душе не ебу, почему оно с таким багом успешно работало.
        Ответить
    • Можно граббить корованы?
      Ответить
      • Именно для этого граббилка и создавалась!
        Ответить
    • Какой багор )))
      #!/usr/bin/python
      import sys
      import requests
      import time
      import threading
      
      HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0'}
      URL = 'http://www.knowops.com/cgi-bin/textenv.pl'
      THREADS = 70
      IP = '1.4.8.8'
      CHECKING_STRING = '/home/knowops1/'
      
      result = []
      result_mutex = threading.Lock()
      
      
      def chunks(lst, n):
          for i in range(0, len(lst), n):
              yield lst[i:i + n]
      
      
      def checker(proxy_list):
          preres = []
          global result
          global IP
          global result_mutex
          global URL
          global HEADERS
          global CHECKING_STRING
      
          for proxy in proxy_list:
              try:
                  proxy = proxy[:-1]
                  response = requests.get(URL, headers=HEADERS, proxies = {'http': 'http://' + proxy}, timeout=8)
                  if response.status_code != 200 and not CHECKING_STRING in response.text:
                      preres += ['bad: ' + proxy]
                      print('status_code: ' + proxy)
                      continue
      
                  if IP in response.text:
                      preres += ['not: ' + proxy]
                      print('not_anon: ' + proxy)
                  else:
                      preres += ['anon: ' + proxy]
                      print('anon: ' + proxy)
      
              except requests.exceptions.Timeout:
                  preres += ['bad: ' + proxy]
                  print('Timeout: ' + proxy)
              except requests.exceptions.ProxyError:
                  preres += ['bad: ' + proxy]
                  print('ProxyError: ' + proxy)
              except requests.exceptions.ConnectionError:
                  preres += ['bad: ' + proxy]
                  print('ConnectionError: ' + proxy)
      
          result_mutex.acquire()
          result += preres
          result_mutex.release()
      Ответить
      • def main():
            if (len(sys.argv) < 3):
                print('Usage: {0} <proxies file> <output file>'.format(sys.argv[0]))
                return
        
            proxies = []
            with open(sys.argv[1], 'r') as f:
                proxies = f.readlines()
            
            proxies = list(chunks(proxies, len(proxies) // THREADS + 1))
            threads = []
        
            for i in range(len(proxies)):
                threads += [threading.Thread(target=checker, args=[proxies[i]])]
        
            for i in range(len(proxies)):
                threads[i].start()
        
            print('{0} threads started'.format(len(proxies)))
                
            for i in range(len(proxies)):
                threads[i].join()
        
            print('writing')
        
            with open(sys.argv[2], 'w') as f:
                for x in result:
                    f.write(x + '\n')
        
        
        if __name__ == '__main__':
            main()
        Ответить
        • for i in range(len(proxies)):
                  threads[i].start()

          Абсолютно классическое говно - обращение по индексу вместо foreach.
          Ответить
          • Мне больше за «global» стыдно.
            Ответить
            • Ну не смертельно, если честно. А вот индексы бесят.
              Ответить
            • Не надо ничего стыдиться. Вообще. Кривым кодом на локалхосте ты можешь сделать хуже только себе, других это не касается.
              Ответить
      • result_mutex.acquire()
            result += preres
            result_mutex.release()

        with, да и это не нужно - все сишные методы синхронизированы, так?
        Ответить
        • Несмотря на «GIL», у «Python» с атомарностью всё плохо: https://blog.qqrs.us/blog/2016/05/01/which-python-operations-are-atomic/. Но конкретно в этом случае, скорее всего, «+=» действительно атомарен.
          Ответить
      • global нужен только если ты хочешь писать в глобальную переменную, или уже стало правилом хорошего тона писать его даже если ты из нее читаешь?
        Ответить
        • > только если ты хочешь писать в глобальную переменную
          This. Я тогда не разобрался в тонкостях областей видимости и глобальных пельменных «Питона».
          Ответить
          • Я бы вообще не рекомендовал глобальные переменные - повторное использование кода, втч для тестов, теряется.
            Ответить
            • Разумеется. Модифицируемые глобальные пельменные — в 99% случаях повод серьёзно пересмотреть рахитектуру.
              Ответить
      • Ксатит, у инхо походу тот скрипт, который делает урлы кликабельными, портит ссылки в литералах типа 'http://govnokod.ru/' и делает кавычку частью урла.
        Ответить

    Добавить комментарий