使用http-conduit
我想下载任何页面的原始维基媒体标记,例如维基百科页面Stack Overflow
。
此外,我希望该解决方案适用于 wikimedia 页面以外的其他页面en.wikipedia.org
,例如de.wikibooks.org
.
笔记:这个问题立即以问答形式回答,因此故意不显示研究成果!
使用http-conduit
我想下载任何页面的原始维基媒体标记,例如维基百科页面Stack Overflow
。
此外,我希望该解决方案适用于 wikimedia 页面以外的其他页面en.wikipedia.org
,例如de.wikibooks.org
.
笔记:这个问题立即以问答形式回答,因此故意不显示研究成果!
此问题使用 http-conduit 中的查询参数,如上一个 SO 答案中所述。
我们将使用SO上描述的方法来下载页面的标记内容。
尽管使用mediawiki可以完成此任务,但在?action=raw
不显式使用 API的情况下使用该方法似乎要简单得多。
为了支持不同的页面(例如en.wikimedia.org
),我编写了两个函数getWikipediaPageMarkup
和getEnwikiPageMarkup
,前一个更通用并且允许使用自定义域(任何域都可以工作,假设 Mediawiki 安装在 下/wiki
)。
{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Conduit
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Lazy.Char8 as LB
import Network.HTTP.Types (urlEncode)
import Data.Monoid ((<>))
-- | Get the Mediawiki marup
getWikipediaPageMarkup :: ByteString -- ^ The wikipedia domain, e.g. "en.wikipedia.org"
-> ByteString -- ^ The wikipedia page title to download
-> IO LB.ByteString -- ^ The wikipedia page markup
getWikipediaPageMarkup domain page = do
let url = "https://" <> domain <> "/wiki/" <> urlEncode True page
request <- parseUrl $ B.unpack url
let request' = setQueryString [("action", Just "raw")] request
fmap responseBody $ withManager $ httpLbs request'
-- | Like @getWikipediaPageMarkup@, but hardcoded to 'en.wikipedia.org'
getEnwikiPageMarkup :: ByteString -> IO LB.ByteString
getEnwikiPageMarkup = getWikipediaPageMarkup "en.wikipedia.org"
请注意,为了编译代码,http-conduit
需要最新版本(最低:2.1
,已测试)。2.1.4