Увы, я еще не могу сказать, что постиг haskell) Но процесс изучения движется, хоть и времени на него остается все меньше и меньше.Haskell — пока еще единственный язык программирования, в котором есть оператор «фтопку»© http://absurdopedia.wikia.com/
В качестве первой попытки написать что-нибудь рабочее и полезное я выбрал сборщик гуглохаков с www.exploit-db.com, код которого и опишу в данной заметке.
Haskell - очень любопытный язык программирования. Бывает, что в процессе его изучения ты думаешь, что вот-вот постигнешь его - но через день понимаешь, что еще далек до просветления)
Но не стоит разводить лирику - многие и так считают меня фанатиком. Поэтому пару слов как и зачем.
Несмотря на то, что сборщик - штука полезная, все, что я опишу здесь - в основном предназначено для меня самого. Привести мысли в порядок, понять, что я уже четко осознаю, а что - еще нет. Поэтому код будет далек от совершенства, хотя изначально я хотел добиться именно его) Однако, в виду отсутствия достаточного количества свободного времени, я решил пока остановиться на том, что хотя бы работает.
Да-да, не стесняемся, пишем в vim'е) К тому же есть замечательные плагины neco-ghc и haskell.vim (первый добавляет omnicomplete для haskell, второй - разные приятные мелочи).
Ну а теперь немного о том, что из себя представляет код сборщика.
Во-первых, гуглохаки расположены по адресу www.exploit-db.com/ghdb/{number}, где number - это порядковый номер хака. Соответственно, в программе нам необходимо будет загружать эту страницу и выбирать в ней значение атрибута href у первой ссылки, которая последует за первым на странице заголовком второго уровня h2.
Во-вторых, для разбора html будем использовать известный и, на мой взгляд, невероятно удобный пакет HXT. Соответственно, понадобится его установить:
cabal install hxt
Теперь непосредственно к коду. Для начала подключим все необходимые библиотеки:
import System.Environment import Text.HandsomeSoup import Text.XML.HXT.Core import Control.Monad import System.IO
System.Evironment & System.IO - для получения входных параметров и вывода собранных хаков в файл. Text.HandsomeSoup - для загрузки разметки страницы. Text.XML.HXT.Core - для разбора страницы и поиска на ней тегов.
У нас будет всего 3 функции, одна из которых будет точкой входа:
main = do [number,filePath] <- getArgs outh <- openFile filePath WriteMode result <- collect outh (read number :: Int) hClose outh
Для начала в number и filePath получаем необходимые параметры - сколько хаков собрать и в какой файл их записать. Затем с помощью функции openFile открываем выбранный файл для записи, а его хендл помещаем в outh для дальнейшего использования. Затем вызываем функцию сбора хаков collect, передавая ей на вход файл и количество хаков, приведенное к целому числу. После всех операций закрываем файл.
Основная функция сборки выглядит так:
collectHelper file 0 exploits = return exploits collectHelper file number exploits = do doc <- fromUrl . exploitDbUrl $ number exploit <- runX $ doc >>> css "h2 a" >>> getAttrValue "href" hPutStrLn file (head exploit) collectHelper file (number - 1) (exploit:exploits) collect file number = collectHelper file number []
Она разбита на две части для удобного использования рекурсии. Собственно, collect просто передает параметры collectHelper'у, а заодно и список, в который та будет добавлять новые найденные хаки в виде строк.
В самом collectHelper сначала укажем, что остановимся и вернем результат, когда число не пройденных хаков number достигнет нуля. Затем реализуем основную нагрузку.
Для начала, загрузим разметку по адресу, который сформируем из исходного плюс номер страницы, с помощью функции fromUrl. Эта функция конкатенирована с exploitDbUrl, которая возвращает строку исходного адреса с помощью оператора "·" (точка) :
exploitDbUrl number = "http://www.exploit-db.com/ghdb/" ++ show number ++ "/"
С помощью оператора "$" передаем в итоговую конкатенированную функцию параметр number - номер страницы. Результат помещаем в doc.
Затем с помощью HXT начинаем поиск нужных тегов. Для начала вызываем runX(напрямую функции из HXT не вызвать) и передаем в параметрах описание того, что хотим сделать. В данном случае указываем, что в документе doc необходимо найти тег с типом h2, а в нем тег ссылки a, и извлечь из этой ссылки значение атрибута href.
После всех этих действий тут же запишем полученный хак в файл функцией hPutStrLn и вновь вызовем эту же функцию, добавив новый гуглохак в список и уменьшив количество не обойденных страниц на единицу (а вот и первый косяк - результатом этого является массив строк, из которого надо выбрать первую и передать дальше, а я почему-то передаю весь массив)).
На этом код завершен) Расположен он здесь. Дальше дело техники - скомпилировать и запустить:
ghc -o collector collector.hs ./collector 10 exploits



0коммент.:
Отправить комментарий