Я постоянно признаю, что плохо разбираюсь в объективах, но разве учиться на примерах — это не хорошо? Я хочу взять HTML, разобрать его с помощью taggy-lens
, а затем удалить все элементы script
изнутри. Вот моя попытка:
#!/usr/bin/env stack
-- stack --resolver lts-7.1 --install-ghc runghc --package text --package lens --package taggy-lens --package string-class --package classy-prelude
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
import ClassyPrelude
import Control.Lens hiding (children, element)
import Data.String.Class (toText, fromText, toString)
import Data.Text (Text)
import Text.Taggy.Lens
import qualified Text.Taggy.Lens as Taggy
import qualified Text.Taggy.Renderer as Renderer
somehtmlSmall :: Text
somehtmlSmall =
"<!doctype html><html><body>\
\<div id=\"article\"><div>first</div><div>second</div><script>this should be removed</script><div>third</div></div>\
\</body></html>"
renderWithoutScriptTag :: Text
renderWithoutScriptTag =
let mArticle :: Maybe Taggy.Element
mArticle =
(fromText somehtmlSmall) ^? html .
allAttributed (ix "id" . only "article")
mArticleFiltered =
fmap
(\el ->
el ^.. to universe . traverse .
filtered (\n -> n ^. name /= "script"))
mArticle
in maybe "" (toText . concatMap Renderer.render) mArticleFiltered
main :: IO ()
main = print renderWithoutScriptTag
Отметьте этот файл как исполняемый и просто запустите его, и вы увидите:
➜ tmp ./scraping-question.hs
"<div id=\"article\"><div>first</div><div>second</div><script>this should be removed</script><div>third</div></div><div>first</div><div>second</div><div>third</div>"
Итак, это не сработало. Я хотел бы:
- есть рабочее решение
- понять рабочее решение
Был бы особенно благодарен, если бы вы помогли мне понять, что не так с моим. Спасибо!
Taggy.Element
и возвращает отфильтрованноеTaggy.Element
. Затем напишите отдельную функцию, обрабатывающую преобразование из/в текст вокруг этого, что, вероятно, можно сделать довольно прямо через призму. - person dfeuer   schedule 01.10.2016