Многие, кто только начал изучать Haskell сразу лезут в Web. Причем лезут с двух сторон, с одной стороны это web-пауки, а с другой сайты и порталы.
При наличии великолепных web-фреймворков вроде Snap или Yesod, написание CMS для сайта не является подвигом.
А вот с web-crawler'ами новичку будет сложнее. Наиболее удобной библиотекой является Shpider.
Установить её можно с помощью cabal:
cabal install shpiderИтак, приступим.
Сперва взглянем на тип Shpider, с ним нам придется все время работать:
type Shpider = StateT ShpiderState IOМы имеем state transformer monad с состоянием ShpiderState и используемой "внутри" IO монадой. ShpiderState мы разберем чуть позже.
Т.к. мы работаем со state transformer monad, то любые действия надо будет выполнять через подобие runState - runShpider.
Главный модуль называется Network.Shpider, его мы и импортируем:
import Network.ShpiderНачнем с простых примеров:
a1 = runShpider $ download "http://kreed131.blogspot.com/"Функция download возвращает tuple из ShpiderCode и Page. ShpiderCode, как написано в документации, описывает различные непредвиденные ситуации, которые могут случиться во время краулинга. Грубо говоря, это "return code", который оповещает нас о том, все ли хорошо прошло.
Тип Page содержит в себе исходный код страницы, все формы со страницы, все гиперссылки со страницы, адрес страницы и "Tag Soup". С "Tag Soup" вы скорее всего и продолжите работать, для этого вам понадобится модуль Text.HTML.TagSoup.
Библиотека tagsoup позволяет удобно работать с валидными и невалидными html/xml документами.
С runShpider мы можем использовать do-нотацию:
-- | Получим html-код страницыВсе вроде понятно. Но вот незадача: некоторые сайты шлют нас лесом, им видите-ли, наш пустой user-agent не нравится. А еще cookies нет. Что же делать?a2 = runShpider $ dos <- download "http://kreed131.blogspot.com/"return (source $ snd s)-- | Или гипперссылкиa2 = runShpider $ dos <- download "http://kreed131.blogspot.com/"return (links $ snd s)-- | Заполним форму a3 = runShpider $ do f <- fmap (head . forms . snd) $ download "http://www.yandex.ru/" sendForm $ fillOutForm f $ pairs $ do "login" =: "helloworld" "password" =: "superpassword"
Тут нам и приходит на помощь ShpiderState.
ss = SS { startPage = "" , htmlOnlyDownloads = False , dontLeaveDomain = False , curlOpts = [ CurlCookieFile "cookies" , CurlCookieJar "cookies" , CurlUserAgent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.27 \ \(KHTML, like Gecko) Chrome/12.0.718.0 Safari/534.27 ] , currentPage = emptyPage , visited = Nothing }Теперь мы определили наш user-agent и cookies будут сохраняться в файле "cookies". Shpider "под капотом" имеет всем знакомый curl, поэтому о параметрах curlOpts подробнее можно посмотреть тут.
Теперь настало время включить наш ShpiderState. Сделать это очень просто:
a2 = runShpider $ do
put ss -- вводим наш state s <- download "http://kreed131.blogspot.com/" return (links $ snd s)Вот и все! Web-crawling на Haskell доступен всем! ;)
Комментариев нет:
Отправить комментарий