Скрипт проверяющий прокси

Discussion in 'PHP' started by Ardling, 8 Sep 2009.

  1. Ardling

    Ardling New Member

    Joined:
    30 Aug 2009
    Messages:
    23
    Likes Received:
    3
    Reputations:
    0
    Не нашел никакой программы для linux, которая бы умела проверять прокси на работоспособность.

    Возможно выход в такой ситуации написать скриптик самому, но встало два вопроса:
    На чем писать
    Самый очевидный выбор для linux это bash или perl, но у меня почти не т опыта программирования и на том и на другом.
    Как выриант можно писть на python, с которым я немножко имел дело, но все равно хотелось бы услышать аргументированное мнение по поводу выбора языка.

    Что писать
    Опять у меня совсем нет опыта программирования для сети. Из баша можно запускать ping или httping, но похоже что это не самый удачный способ проверки проксей, посему прошу предложить спосб луше.

    В случае с питоном вопрос проверки еще более тумант.

    Буду благодарен за любые ссылки на маны и документацию и вообще ссылки на любые марериалы по теме, можно на языке вероятного противника.
     
  2. FireFenix

    FireFenix Elder - Старейшина

    Joined:
    3 Jun 2009
    Messages:
    390
    Likes Received:
    115
    Reputations:
    23
    Где вас только таких берут? или мама поиском не научила пользоваться?

    иду я в поиск и что я вижу?
    python -> http://forum.antichat.ru/showpost.php?p=1268835&postcount=1
    обсуждение "proxy cheker, консольный для nix" -> http://forum.antichat.ru/showthread.php?t=116388
    php чекер -> http://forum.antichat.ru/showthread.php?p=1158954-proxy+%F7%E5%EA%E5%F0#post1158954
    Ещё одна общая доработка perl чекера -> http://forum.antichat.ru/threadnav40897-104-10.html

    при большом желании найти можно всё..... но вот задавать глупые вопросы - это всегда пожалуйста!
     
  3. Ardling

    Ardling New Member

    Joined:
    30 Aug 2009
    Messages:
    23
    Likes Received:
    3
    Reputations:
    0
    Спасибо. Подборка хорошая. Ошибку понял.

    Тем не менее за буду весьма признателен, если кто-то поделится опытом по выше озвученным вопросам, так как видимо буду либо подгонять скрипты под себя, либо все равно писать свои. Посмотрим что будет попроще.
     
    #3 Ardling, 8 Sep 2009
    Last edited: 8 Sep 2009
  4. eLWAux

    eLWAux Elder - Старейшина

    Joined:
    15 Jun 2008
    Messages:
    860
    Likes Received:
    616
    Reputations:
    211
    forum.antichat.ru/showpost.php?p=1491575&postcount=6
     
  5. Ardling

    Ardling New Member

    Joined:
    30 Aug 2009
    Messages:
    23
    Likes Received:
    3
    Reputations:
    0
    В итоге, после долгих блужданий по форуму так и не нашел нормального чекера на python и решил сам написать что-то подобное. Возможно кому-то это пригодится, ибо написанное на питоне очень удобно подстраивать под свои конкретные нужды.

    PHP:
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-

    import socket
    import urllib2
    import threading

    openUrl 
    'http://2ip.ru/'
    proxiesFileName 'proxies-big'
    outFileName 'goodproxies'
    timeout 5
    maxProxyNum 
    100

    class fileLister:
        
    def __init__(selffileName):
            
    with open(fileName'r') as file:
                
    self.fileList file.readlines()

        
    def getProxyAdress(self):
            return {
    'http''http://'+self.fileList.pop().strip()}
        
        
    def isNotEmpty(self):
            if 
    len(self.fileList) == 0:
                return 
    False
            
    else: return True

    def checkThread
    ():
        while 
    proxyFile.isNotEmpty():
            
    checkProxy(proxyFile.getProxyAdress())

    def checkProxy(proxyAdress):
        
    proxyHandler urllib2.ProxyHandler(proxyAdress)
        
    opener urllib2.build_opener(proxyHandler)
        
    urllib2.install_opener(opener)
        
        try: 
    urllib2.urlopen(openUrl)
        
    except urllib2.URLErroreproxyErr(proxyAdresse)
        else: 
    goodProxy(proxyAdress)

    def proxyErr(proxyAdresserror):
        
    proxyName proxyAdress.values()[0][7:]
        
    with printLock:
            print 
    proxyNameerror.errnoerror.reason

    def goodProxy
    (proxyAdress):
        
    proxyName proxyAdress.values()[0][7:]
        
    with printLock:
            print 
    proxyName"Работает"
        
    with open(outFileName'a') as file:
            print>>
    fileproxyName

    def main
    ():
        global 
    printLock
        printLock 
    threading.Lock()

        
    socket.setdefaulttimeout(timeout)
        
        global 
    proxyFile
        proxyFile 
    fileLister(proxiesFileName)
        
        for 
    i in xrange(maxProxyNum):
            
    threading.Thread(target=checkThread).start()

    if 
    __name__ == '__main__':
        
    main()
    Хотелось бы услышать что вы о моем тварении думаете, желательно разумную критику. Интересно было бы услышать чего еще полезного можно к этому скрипту прикрутить.
     
    1 person likes this.
  6. login999

    login999 Elder - Старейшина

    Joined:
    12 Jun 2008
    Messages:
    491
    Likes Received:
    280
    Reputations:
    92
    Ну кагбэ майн имха такова : первый минус - что грузишь файл в оперативку, тут можно обойтись итератором
    <дальше не читать>
    Code:
    [SIZE=1]
    , хотя лучше использовать queue и динамическую прогрузку - сделать iter(filehandler) и в вечном цикле до stopIteration гонять этот файлхендлер, queue же заюзать тупо как буффер и сделать его размер где-то так :threads_count*2(3) тогда потоки у тебя будут постоянно получать задачи, и можно будет сделать красивую обработку ошибок (хотя не стоять, я не туда уже поплыл, для чекера проксей это пох ибо что так что эдак это не катит именно для [U]чекера проксей[/U])[/SIZE]
    
    </дальше не читать>

    А вообще в принципе нормально, но имхо уж больно много функций ) Лучше сделай пару функций покрупнее, а не 10 одно-двухстрочных )

    P.S. Кагбэ интересно, а он нормально работает ?
    Попробуй прочекать в 10 потоков 100 прокси - чето мне подсказывает что вывод прокси будет только один раз, ибо не катит
    Code:
    printLock = threading.Lock()
    
    лучше бы
    Code:
    printLock = threading.RLock()
    
    Потом, при длительной работе/большом количестве потоков могут повылазить эксепшны, не айс использовать замок для вывода в консоль - с этим траблов не буит, а вот многопоточный вывод в файл может запросто убить его, лучше сделай отдельную функцию вывода в файл и юзай там глобальный замок, и вообще глобал не айс )
     
    #6 login999, 15 Sep 2009
    Last edited: 15 Sep 2009
  7. Ardling

    Ardling New Member

    Joined:
    30 Aug 2009
    Messages:
    23
    Likes Received:
    3
    Reputations:
    0
    Я думал об этом, но мне показалось сомнительным, что читать с диска по одной скажем несколько сотен строчек - просто насилие над диском. Тем более что сам я не юзаю пока списки по нескольку тысяч прокси. Возможно хорошим решением будет сливать с диска по сотне строк за раз.
    У меня то что ты написал в теге CODE отображается с горизонтальной прокруткой почему-то. Читать невозможно!!!

    Теперь буду долго пытаться понять что ты мне там написал, и возможно меня за мои труды ждет озарение.
    Я помнится у Кернигана и Ричи вычитал, что функции не должны быть длинными и использоваться везде, где требется повторять ког, или если это отражает структуру программы.

    А вообще проще изменять функциональность отдельных функций (вот такой я поэт), а в будущем одни скорее всего потолстеют.
    Тут как раз все хорошо, по крайней мере кроме записи на диск, хотя и с ней косяков не замечено. Поясняю зачем Lock на вывод - если несколько процов на компе (или ядер) то пара потогов вместе начинает выводить на экран, и вылезает белиберда. На однопроцессорной конфигурации таких проблем нет и лок излишен.

    С выводом в файл проблем не замечено, подозреваю что with решает).

    global - это ужасно, на C я бы за такое все бы поотрывал. Но в питоне области видимости - больная тема, и я не нашел более красивого решения. Не хочу мутить новый объект тк просто можно скрипт подключать как модуль и юзать функции. Оч удобно на мой взгляд.
     
  8. login999

    login999 Elder - Старейшина

    Joined:
    12 Jun 2008
    Messages:
    491
    Likes Received:
    280
    Reputations:
    92
    Эх, не о том мну Lock (если исходить из манов) один поток может вызывать только один раз, RLock один поток может вызывать несколько раз подряд.
    P.S. Насчет монструозности - мну бывает заносит, начинаю изь*бываться.
    Несколько процов/ядер пох ибо это threading а не multiprocessing, параша в консоль валится это бесспорно, в принципе, сделай так (ну попиарю я WRITER :))
    Code:
    #Класс для записи данных в несколько файлов
    class WRITER:
        
        #Атрибут инициализации
        def __init__(self):
            
            from threading import RLock
            
            self.Lock = RLock
            self.Locks = {}
            
            self.defaultencoding = "UTF-8"
            self.defaultout = u"out"
        
        #Атрибут записи одного элемента
        def write_one(self, data, id_=None, data_encoding=None):
            if id_ is None:
                id_ = self.defaultout
            if data_encoding is None:
                encoding = self.defaultencoding
            if id_ not in self.Locks:
                self.Locks[id_] = self.Lock()
            self.Locks[id_].acquire()
            with open(u"{0}.csv".format(id_).encode(self.defaultencoding), "a") as out:
                print data
                out.write("{0}\n".format(data.encode(encoding, "replace")))
            self.Locks[id_].release()
        
        #Атрибут записи последовательности
        def write_many(self, data, id_=None, data_encoding=None):
            if id_ is None:
                id_ = self.defaultout
            if data_encoding is None:
                encoding = self.defaultencoding
            if id_ not in self.Locks:
                self.Locks[id_] = self.Lock()
            self.Locks[id_].acquire()
            with open(u"{0}.csv".format(id_).encode(self.defaultencoding), "a") as out:
                for item in data:
                    print item
                    out.write("{0}\n".format(item.encode(encoding, "replace")))
            self.Locks[id_].release()
    
    Данные ему давать в юникоде )
    Потом, еще раз, в той куче монструозности есть еще один класс - PROXYS, его тоже можешь глянуть, при малюсенькой корректировке им можно заменить твой скрипт (добавить только вывод в файл и вывод в консоль, замки там уже имеются). П.С. насчет критики моей ты можешь не нервничать, по большому счету мне все равно как ты напишешь своё творение, мои посты можешь рассматривать просто как ещё один возможный вариант решения своей задачи.
    П.С. смотри аву - мну мудак )
    P.P.S. WRITER задуман для вывода данных в несколько разных файлов, это просто мойне парашен, в стандартной поставке есть logging, назначение его в принципе другое, но его можно переделать под аналогичные задачи, а так то мне лень было с ним разбираться =/
     
    #8 login999, 15 Sep 2009
    Last edited: 15 Sep 2009