Как просканировать сайт на JPG-картинки

Discussion in 'Linux, Freebsd, *nix' started by M.Billar, 20 Jul 2019.

  1. M.Billar

    M.Billar Member

    Joined:
    24 Jul 2013
    Messages:
    84
    Likes Received:
    65
    Reputations:
    0
    Вот есть image-хостинг, у которого стандартный URL вида: http://hosting.com/d/Hdj3bXHnd
    и вот само название картинки там формируется из символов в обоих регистрах и цифр, причем последние картинки загружаются с поочередными именами (напр: Hdj3bXHn1, Hdj3bXHn2).

    Как лучше всего брутить картинки, имея возможность указать начальный URL для перебора названий картинок? Т.е указать например Hdj3bXHn1, и брут начинает перебирать все варианты: Hdj3bXHn2...Hdj3bXHN1...Hdj3bXHN2 и т.д.

    Спасибо за помощь
     
    #1 M.Billar, 20 Jul 2019
    Last edited: 20 Jul 2019
  2. Baskin-Robbins

    Baskin-Robbins Reservists Of Antichat

    Joined:
    15 Sep 2018
    Messages:
    239
    Likes Received:
    809
    Reputations:
    212
    Ну наверное самым простым будет создание словаря из всех возможных значений 9 символьных имен картинок и запустить брут, на основании ответов уже определяешь есть или нет картинка, но думаю для этого
    придется написать скриптик
    Если есть возможность узнать имя одной из старейших картинок и правила формирования имен(я имею ввиду каким образом вставляются буквы разных регистров) то можно сократить время создав словарь
    от имени самой старой картинки которую сможешь найти до текущих имен по порядку на основе правила присвоения имен
    Hdj3bXHn2
    Hdj3bXHn3
    ...
    Hdj3bXHn9
    Hdj3bXHо0
    Hdj3bXHо1
    ...
    Hdj3bXHz9
    Hdj3bXHA0
    Hdj3bXHA1
    ...
    Hdj3bXHZZ
    Hdj3bXJ00
    Hdj3bXJ01

    P.S.
    Словарик получится не маленький)
     
    M.Billar likes this.
  3. M.Billar

    M.Billar Member

    Joined:
    24 Jul 2013
    Messages:
    84
    Likes Received:
    65
    Reputations:
    0
    Это я все +- понимаю, и исходя из длины в 8 символов, а так-же того факта, что у новых картинок самые первые буквы одинаковые, то перебор сокращается до 5-6 символов

    Написал (googled same) такой скриптец для теста, и 50.000 картинок в рандоме чекает сравнительно быстро в хроме, на ультрабуке с 3им поколением Intel Core. Гуглин подсказал, что есть вариант все быстро собрать через wget с использованием регулярок, но я вот не могу понять как сформировать регулярку для wget по данному шаблону

    jquery не забудьте подключить
    Code:
    <html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"><script src="./jquery.js"></script><script>function getRandomLink() {
            var c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            var link = '';
            for(var i = 0; i < 3; i++) {
                link += c.charAt(Math.floor(Math.random() * c.length));
            }
            return link;
        }
        for(var i = 0; i < 50000; i++){
            var randomLink = getRandomLink();
            document.write('<img src="http://tlgur.com/d/GPVAb'+randomLink+'">');
        }
        $('img').error(function(){
            $(this).remove();
        });
    </script></head><body></body></html>
    
    Потому и раздел данный выбрал для вопроса, нужен линуксоид знающий :) С меня + в карму
     
  4. Baskin-Robbins

    Baskin-Robbins Reservists Of Antichat

    Joined:
    15 Sep 2018
    Messages:
    239
    Likes Received:
    809
    Reputations:
    212
    Насколько быстро?
     
  5. M.Billar

    M.Billar Member

    Joined:
    24 Jul 2013
    Messages:
    84
    Likes Received:
    65
    Reputations:
    0
    2-3 минуты максимум, и то, по моему браузер больше лагает с библиотекой jquery.

    Python скрипт делающий примерно тоже самое работает как не странно - медленнее варианта с браузерами

    Code:
    #!/usr/bin/env python
    import argparse
    import hashlib
    from multiprocessing import Lock
    import os
    import queue
    import random
    import string
    import sys
    import threading
    import time
    from urllib.error import URLError, HTTPError
    from urllib.request import Request, urlopen
    # Constants
    CHARS = string.ascii_letters+string.digits # Characters used for random URLs.
    DIR_OUTPUT = 'output' # Output directory.
    ERRORS_DISPLAY = True # Should all errors display?
    IMAGE_EXTENSION = ".jpg" # Extension for search.
    IMAGE_SIZE_MIN = 300 * 20 # Minimum filesize for downloaded images.
    IMAGES_DEFAULT = 25 # Number of images to download if not specified at command line.
    IMGUR_URL_PREFIX = "http://tlgur.com/d/GPVAb" # Prefix for Imgur URLs.
    THREADS = 100 # Number of threads to spawn.
    # Globals
    queue_image_ids = queue.Queue() # Queue for random images.
    downloaded = 0 # Number of images downloaded.
    # Functions
    def rand_string(string_length):
        return ''.join([random.choice(CHARS) for x in range(string_length)])
    def path_get():
        if sys.platform.startswith('win32'):
            path = os.getcwd()+'\\'+DIR_OUTPUT+'\\'
        else:
            path = os.getcwd()+'/'+DIR_OUTPUT+'/'
        return path
    def path_create():
        path = path_get()
        if not os.path.exists(path):
            os.makedirs(path)
    def error_print(error):
        if ERRORS_DISPLAY:
            print(error)
    # Thread
    class ThreadSpawn(threading.Thread):
        def __init__(self, queue, lock):
              threading.Thread.__init__(self)
              self.queue = queue
              self.lock = lock
        def get_images(self, num_pics):
            path = path_get()
            for i in range(num_pics):
                success = False
                while not success:
                    image_name = rand_string(3)
                    url = IMGUR_URL_PREFIX+image_name
            
                    req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})
                    data = None
                    try:
                        data = urlopen(req)
                    except HTTPError as e:
                        errorss = str(e.code)
                    except URLError as e:
                        errorsss = str(e.reason)
                    if data:
                        try:
                            data = data.read();
                            # Check if placeholder image.
                            if 'd835884373f4d6c8f24742ceabe74946' == hashlib.md5(data).hexdigest():
                                error_print("Received placeholder image: "+image_name)
                            # Check if image is above minimum size.
                            elif IMAGE_SIZE_MIN > sys.getsizeof(data):
                                error_print("Received image is below minimum size threshold: "+image_name)
                            # Write image to disk.
                            else:
                                success = True
                                self.local_file = open(path+image_name+IMAGE_EXTENSION, "wb")
                                self.local_file.write(data)
                                self.local_file.close()
                                lock.acquire()
                                global downloaded
                                downloaded += 1
                                lock.release()
                                print("Downloaded image #"+str(downloaded)+": "+image_name)
                            del data
                        except:
                            error_print("Download failed: "+image_name)
        def run(self):
            while True:
                # Grabs num from queue - note that num is arbitrary and isn't used.
                num = self.queue.get()
                # Grabs a pic.
                self.get_images(1)
                # Signals to queue job is done.
                self.queue.task_done()
    # Main
    if __name__ == '__main__':
        time_start = time.time()
        # Parse arguments.
        parser = argparse.ArgumentParser()
        parser.add_argument('-e', '--errors', type=str, default='True', help='Toggle error messages on and off. (Default: True)')
        parser.add_argument('-i', '--images', type=int, default=IMAGES_DEFAULT, help='Number of images to download. (Default: '+str(IMAGES_DEFAULT)+')')
        parser.add_argument('-min', '--min-size', type=int, default=IMAGE_SIZE_MIN, help='Minimum image size in bytes. (Default: '+str(IMAGE_SIZE_MIN)+')')
        parser.add_argument('-o', '--output', type=str, default=DIR_OUTPUT, help='Output folder name. (Default: '+str(DIR_OUTPUT)+')')
        parser.add_argument('-t', '--threads', type=int, default=THREADS, help='Number of threads to spawn. (Default: '+str(THREADS)+')')
        args = parser.parse_args()
        # Error messages.
        if args.errors in ['false','False','No','no','0']:
            ERRORS_DISPLAY = False
        # Minimum image size
        IMAGE_SIZE_MIN = args.min_size #TODO: Do not overwrite CONSTANTS.
        print("Minimum image size is: "+str(IMAGE_SIZE_MIN))
        # Image path.
        DIR_OUTPUT = args.output #TODO: Do not overwrite CONSTANTS.
        path_create()
        print('Output folder is: "'+path_get()+'"')
        # Image limit.
        image_limit = args.images
        print('Retreiving '+str(image_limit)+' random images.')
        # Populate queue with data.
        for n in range(image_limit):
            queue_image_ids.put(n)
     
        # Create shared lock.
        lock = Lock()
     
        # Spawn a pool of threads, and pass them queue instance.
        print("Spawning "+str(args.threads)+" threads.\n")
        for i in range(args.threads):
            t = ThreadSpawn(queue_image_ids, lock)
            t.daemon = True
            t.start()
        # Wait on the queue until everything has been processed.
        queue_image_ids.join()
        # Completion.
        time_end = time.time()
        time_total = round(time_end - time_start, 2)
        rate = round(time_total / image_limit, 2)
        print("\n")
        print('Completed in: '+str(time_total)+' seconds.')
        print("Approximately "+str(rate)+' seconds per image.')
    

    + не могу понять почему питон при настройке в 200+ потоков словно начинает работать не правильно, и потоки словно провисают. Не думаю что сервер банит.
    Есть идеи?) Вот данный скрипт работает, картинки парсит, но, скорость оставляет желать лучшего:( Да и то что строка рандомная генерится, возможны повторы + проблема с желанием пробрутить все варианты. Вот хз как реализовать брут линейно перебирая все варианты, с возможностью стопать и запускать с последнего места
     
    Baskin-Robbins likes this.
  6. Baskin-Robbins

    Baskin-Robbins Reservists Of Antichat

    Joined:
    15 Sep 2018
    Messages:
    239
    Likes Received:
    809
    Reputations:
    212
    Ну если такая скорость то можно ничего не придумывать))
    как-то сомневаюсь что вгетом можно быстрее это всё дело осуществить
    попробовал курлом - от 2 до 6 сек на запрос, думаю вгет не быстрее робит
     
    VKAPI likes this.
  7. M.Billar

    M.Billar Member

    Joined:
    24 Jul 2013
    Messages:
    84
    Likes Received:
    65
    Reputations:
    0
    а если пытаться получить изначально только заголовок? и проверять на content-type: image/jpeg
     
  8. Baskin-Robbins

    Baskin-Robbins Reservists Of Antichat

    Joined:
    15 Sep 2018
    Messages:
    239
    Likes Received:
    809
    Reputations:
    212
    я получал только заголовки и проверял на код ответа 200 или 404
    видишь суть в том что на sh что-то придумывать под такие задачи не оч здорово, сам по себе баш медленный, тот же пайтон в разы быстрее
    я можешь скинуть ссылку на статью или что ты там нашел по вгет
     
    M.Billar likes this.
  9. M.Billar

    M.Billar Member

    Joined:
    24 Jul 2013
    Messages:
    84
    Likes Received:
    65
    Reputations:
    0
    https://stackoverflow.com/questions...ad-all-images-into-a-single-folder-from-a-url
    https://superuser.com/questions/39374/how-can-i-fetch-the-images-of-a-public-website-using-wget
    https://gist.github.com/tayfie/6dad43f1a452440fba7ea1c06d1b603a

    и след указывающий на возможный REGEX: https://stackoverflow.com/questions/43534380/wget-obtaining-files-matching-regex


    я тупо не умею регулярки составлять в таких случаях, и уже намертво запутался в аргументах wget... поможете, синьйор?)
     
  10. Baskin-Robbins

    Baskin-Robbins Reservists Of Antichat

    Joined:
    15 Sep 2018
    Messages:
    239
    Likes Received:
    809
    Reputations:
    212
    да и так помогаю чем могу
    еще вопрос - ты проверял результаты перебора своим скриптом, он правильно всё нашел?
     
  11. M.Billar

    M.Billar Member

    Joined:
    24 Jul 2013
    Messages:
    84
    Likes Received:
    65
    Reputations:
    0
    на JS и Python да, результаты выпадают с тестами без пропущенных (как я почти уверен, но возможно и не прав)
    Причем до сих пор удивляет как быстро браузер выдает результат по сравнению с тем же питоном...
     
  12. Baskin-Robbins

    Baskin-Robbins Reservists Of Antichat

    Joined:
    15 Sep 2018
    Messages:
    239
    Likes Received:
    809
    Reputations:
    212
    я теперь запутался, ты хочешь скачать изображения по итогу? или просто перебрать адресса с картинками?
    и тебе нужны определенные картинки с определенными адресами?
     
  13. M.Billar

    M.Billar Member

    Joined:
    24 Jul 2013
    Messages:
    84
    Likes Received:
    65
    Reputations:
    0
    мне нужно перебором выхватить с сайта все возможные варианты URL и прочекать их на наличие картинки, все валид картинки сохранить с именем как на сервере в папке
     
  14. Baskin-Robbins

    Baskin-Robbins Reservists Of Antichat

    Joined:
    15 Sep 2018
    Messages:
    239
    Likes Received:
    809
    Reputations:
    212
    Ну смотри, я вижу такой план действий
    находишь путь именно до картинки

    вот так
    [​IMG]

    перебираешь адресса своим скриптом и сохраняешь урл в список допустим lala.txt
    запускаешь вгет
    Code:
    wget -i lala.txt
    картинки сохраняются с теми же именами что и в урл, только что проверил на хостинге картинок
    как-то так)
    ну и соответственно подредактировав скрипт под поиск с разными расширениями картинок
    основных расширений не так уж и много, учитывая твою скорость дополнительные 10 минут на 50к
    не так уж и много, если учитывать что там всего 4 млн файлов и даже если пропустишь
    пару картинок с "особенным" расширением то это несущественно, ну а если прям дотошно нужны все то чутка заморочится придется
    если залиты какие-то еще документы и они скачаются в папке тем же find ом найдешь картинки, хотя учитывая что ты будешь подставлять расширения этого произойти не должно
    ну это как я вижу, может есть способ проще
     
    #14 Baskin-Robbins, 20 Jul 2019
    Last edited: 20 Jul 2019
    winstrool likes this.
  15. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,413
    Likes Received:
    910
    Reputations:
    863
    на примере __vfl.ru там можно эти картинки краулем собрать, так что ту наверное все больше зависит от самого
    объекта, надо его сначала изучить, а потом думать, что да как.
     
    _________________________
    Spinus and Baskin-Robbins like this.