Предисловие: Статья расказывает словами, то что я расказывал в предидущем скринкасте. Я ее не думал как-то публиковать, но потом решил что можеш некоторые вещи станут более понятнее, чем после просмотра видео.
Предисловие 2: статья готовилась не для блога, поэтому может быть не полностью соблюдены зависимости, так что за это извиняюсь.
Сколько языков программирования ты знаешь - один? два? а может быть десять? И в каждом есть свои плюсы и минусы. Но один с языков сейчас у многих на слуху, про него много пишут, много говорят, а если верить ведущим подкаста Радио-Т, то его даже используют в больших песочницах, таких как Яндекс. И этот язык Python, вот о нем и поговорим.
О Python есть несколько статей, но к сожалению они не дадут знаний для использования Python в хакерских целях. Ведь вывод букв и суммирования 2 + 2 хоть и важно, но для того чтобы начать практически использовать Python нам более важнее многопоточность, робота с сетью и сохранение результатов нашей роботы. И обо всем это можете прочитать тут. Поехали ;)
Но перед прочтением рекомендую ознакомится с какой-то начальной статьей о Python, но это не обязательно и можно обойтись без этого.
###Подготовка рабочего места###
Для роботы с Python нам нужно установить сам непосредственно интерпретатор версии 2.5. Дальше нужно скачать библиотеку для роботы с сетью c Python pycURL и снова же понажимать "Next" не изменяя никаких параметров установки.
###Многопоточность###
Начнем погружения в Python и первой вещью которую разберем будет - многопоточность. Многопоточность в Питоне настолько простоя штука, что дальше некуда. Для использования ее нужно объявить библиотеку "thread" через команду "import thread", а дальше можно спокойно запускать любую, абсолютно любую функцию как поток.
Что бы все продемонстрировать давайте объявим простенькую функцию с одной инструкцией "pass" которая ничего не будет делать (в Python нельзя объявить цикл или функцию совсем без инструкций)
ххх
def some_function():
pass
xxx
А теперь можно эту функцию запустить как поток
ххх
thread.start_new_thread(some_function,())
ххх
Ну а поскольку прелесть потоков в их количестве, то можно запустить их побольше, например 10:
xxx
for i in xrange(0,10):
thread.start_new_thread(some_function,())
xxx
Но есть один маленький нюанс. После того как мы запустили потоки главная программа может завершиться и этим завершить роботу потоков. Тоесть нету встроенного средства для контроля того выполняются ли сейчас потоки и их количество. И это можно обойти введя дополнительную переменную которая будет хранить значение количества потоков. Пусть назовем ее "count_thread" и вначале присвоим ей 0, что будет означать количество потоков запущенных равно 0.
xxx
count_thread = 0
xxx
А теперь при каждом запуске потока нужно увеличивать наш флаг на 1:
xxx
for i in xrange(0,sys.argv[3]):
count_thread += 1
thread.start_new_thread(some_function,())
xxx
И в каждую функцию которую планируем запускать как поток добавим изменения, чтобы при завершении своей роботы уменьшал флаг потоков на единицу.
ххх
def some_function():
global count_thread
pass
count_thread -= 1
ххх
В конце же нашей главной программы напишем бесконечный цикл который будет ждать завершения всех потоков
ххх
while (count_thead>0):
pass
ххх
Теперь применяя вышесказанное мы можем легко использовать потоки где захотим.
###Работа с HTTP###
При роботе с сетью я всегда выбираю мощный универсальный инструмент который работает во многих языках программировния, а именно cURL. Поэтому мы в основном рассмотрим лишь как подключить cURL к Python с помощью модуля pycURL и рассмотрим базисы его использования.
Сначала подключим нашу библиотеку pycURL.
xxx
import pycurl
xxx
Чтобы принять данные после запроса и их сохранить библиотека pycURL требует обьявить функцию которая будет принимать данные. Можно конечно и самим написать ее но лучше воспользуемся модулем для роботы со строками StringIO и обьектом с таким же названием как и модель. В этом обьекте есть метод write который идеально подойдет для наших задач. Подключим модуль и обьявим обьект такими строчками:
ххх
import StringIO
data = StringIO.StringIO()
ххх
Теперь можно объявить объект pycURL и настроить его параметры например для осуществления Get запроса на главную страничку xakep.ru:
xxx
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'xakep.ru')
curl.setopt(pycurl.WRITEFUNCTION, data.write)
xxx
Все теперь у нас все готово для запуска запроса и получения результатов:
xxx
curl.perform()
curl.close()
print data.getvalue()
xxx
Манипулируя методом setopt мы можем осуществить очень много разнообразных по функциональности запросов. Например, если добавить нижеуказанные параметры то запрос будет осуществлен через socks размещенным на 2222 порту и с IP:192.168.1.1
xxx
curl.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_SOCKS5)
curl.setopt(pycurl.HTTPPROXYTUNNEL, 1)
curl.setopt(pycurl.PROXY, '192.168.1.1:2222')
xxx
Про все возможности cURL вы можете прочитать на сайте WWW.
###Работа с файловой системой###
После получения результатов для их сохранения мы можем использовать простые текстовые файлы, а для работы с файлами нужно уметь открыть в нужном режиме, например для чтения или записи, или для того и другого. Вот к примеру откроем файл 'input.txt' на чтения, а файл 'output.txt' на запись:
ххх
fi = open('input.txt','r')
fo = open('output.txt','w')
ххх
Теперь давайте попробуем прочитать файл используя простой метод - readlines()
ххх
list = fi.readlines()
ххх
Теперь в переменной list у нас будет находится массив строк с файла input.txt
А запись производить еще проще, например так:
ххх
fo.write('hello XAKEP')
ххх
Ну и не забываем в конце роботы закрыть файлы:
xxx
fi.close
fo.close
xxx
###Практика на реальном примере###
Чтобы все выше сказанное могло обрести конкретную живую и полезную форму напишем исходя с вышеперечисленных знаний маленькую прогу для многопоточной проверки socksов на валидность.
Сначала обьявим нужные нам библиотеки:
ххх
import thread
import StringIO
import pycurl
ххх
Пусть у нас входной список проверяемых socksов будет хранится в файле 'input.txt', а результаты нужно сохранять в файл 'output.txt'. Давайте их откроем и прочитаем:
ххх
fi = open('input.txt','r')
list = fi.readlines()
fo = open('output.txt','w')
ххх
А теперь вспомним многопоточность и вставим следующие в конце файла:
ххх
count_thread = 0
for i in xrange(0,10):
count_thread += 1
thread.start_new_thread(test_socks,())
while (count_thead>0):
pass
fi.close
fo.close
print 'the end ;)'
ххх
И нам осталось лишь функцию test_socks для тестирования sockов. Но прежде подумаем как же брать входящую информацию и как распроделить ее между потоков, что бы они не брали одновременно один и тот же socks для проверки и после проверки его как-то помечали для остальных потоков. Решение у этой проблемы очень простое - все нужные для проверки socksы находятся после прочтения в массиве list. Давайте будем работать с list как со стеком. Тоесть алгоритм такой - берем и вырезаем самый первый элемент с нашего стека list для этого можно использовать метод pop. А поскольку будем вырезать элементы, то этим исключим проверку одного socks несколько раз. И потоки будут брать socks со стека list до тех пор пока в нем есть что брать. Та и к тому же list обьявим глобальным, чтобы он был один для всех функций запущеных как поток. В результате мы получим следующую функцию:
ххх
def test_socks():
global list, fo, count_thread
while ( len(list)>0 ):
proxy = list.pop()
data = StringIO.StringIO()
curl = pycurl.Curl()
curl.setopt(pycurl.FOLLOWLOCATION, 0)
curl.setopt(pycurl.CONNECTTIMEOUT, 20)
curl.setopt(pycurl.URL, 'ya.ru')
curl.setopt(pycurl.WRITEFUNCTION, data.write)
curl.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_SOCKS5)
curl.setopt(pycurl.HTTPPROXYTUNNEL, 1)
curl.setopt(pycurl.PROXY, proxy)
try:
curl.perform()
except:
pass
curl.close()
rez = data.getvalue()
if (len(rez)>100):
fo.write(proxy)
count_thead -= 1
ххх
Единственное что необходим добавить, так это то что при проверке функции использовалась конструкция try, потому что если socks не работоспособный то будет cURL вызовет исключение, а для его подавления и использованили try. А что бы проверить работоспособность проверяем количество байт принятых запросом.
Полные исходники и видео в котором можно увидеть роботу программы найдете на диске.
###Вывод###
Как видно все элементарно и очень просто. Правда это лишь первая часть статьи и чтобы вас немного заинтересовать раскажу что во второй части разберем роботу Python с базами данных и напишем как пример более сложную программу для рекламирования ваших таблеток и магазинов в популярном в USA и не только сервисе микроблогинга Twitter
Вопросы приветствуются