4

最近、TEDのウェブサイトからトークタイトルを取得する必要のあるウェブサイトを作成しました。

これまでのところ、問題はこの話に固有のものです:フランシスコリンズ:私たちはより良い薬が必要です-今

Webページのソースから、次のようになります。

<title>Francis Collins: We need better drugs -- now | Video on TED.com</title>
<span id="altHeadline" >Francis Collins: We need better drugs -- now</span>

さて、ghciで、私はこれを試しました:

λ> :m +Network.HTTP Text.Regex.PCRE
λ> let uri = "http://www.ted.com/talks/francis_collins_we_need_better_drugs_now.html"
λ> body <- (simpleHTTP $ getRequest uri) >>= getResponseBody
λ> body =~ "<span id=\"altHeadline\" >(.+)</span>" :: [[String]]
[["id=\"altHeadline\" >Francis Collins: We need better drugs -- now</span>\n\t\t</h","s Collins: We need better drugs -- now</span"]]
λ> body =~ "<title>(.+)</title>" :: [[String]]
[["tle>Francis Collins: We need better drugs -- now | Video on TED.com</title>\n<l","ncis Collins: We need better drugs -- now | Video on TED.com</t"]]

いずれにせよ、解析されたタイトルは左側のいくつかの文字を見逃し、右側にいくつかの意図しない文字があります。--話のタイトルと関係があるようです。でも、

λ> let body' = "<title>Francis Collins: We need better drugs -- now | Video on TED.com</title>"
λ> body' =~ "<title>(.+)</title>" :: [[String]]
[["<title>Francis Collins: We need better drugs -- now | Video on TED.com</title>","Francis Collins: We need better drugs -- now | Video on TED.com"]]

幸いなことに、これはの問題ではありませんText.Regex.Posix

λ> import qualified Text.Regex.Posix as P
λ> body P.=~ "<title>(.+)</title>" :: [[String]]
[["<title>Francis Collins: We need better drugs -- now | Video on TED.com</title>","Francis Collins: We need better drugs -- now | Video on TED.com"]]
4

1 に答える 1

4

私の推奨事項は次のとおりです。HTMLの解析に正規表現を使用しないでください。代わりに、適切なHTMLパーサーを使用してください。これは、html-conduitパーサーをxml-conduitカーソルライブラリ(およびダウンロード用のhttp-conduit)と一緒に使用した例です。

{-# LANGUAGE OverloadedStrings #-}
import           Data.Monoid          (mconcat)
import           Network.HTTP.Conduit (simpleHttp)
import           Text.HTML.DOM        (parseLBS)
import           Text.XML.Cursor      (attributeIs, content, element,
                                       fromDocument, ($//), (&//), (>=>))

main = do
    lbs <- simpleHttp "http://www.ted.com/talks/francis_collins_we_need_better_drugs_now.html"
    let doc = parseLBS lbs
        cursor = fromDocument doc
    print $ mconcat $ cursor $// element "title" &// content
    print $ mconcat $ cursor $// element "span" >=> attributeIs "id" "altHeadline" &// content

このコードは、SchoolofHaskellでアクティブコードとしても入手できます。

于 2013-03-27T12:25:11.503 に答える