昨天,我尝试在 Network.HTTP 的帮助下用 Haskell 编写一个简单的 rss 下载器。和 Feed图书馆。我想从 rss 项目下载链接,并以该项目的标题命名下载的文件。
这是我的简短代码:
import Control.Monad
import Control.Applicative
import Network.HTTP
import Text.Feed.Import
import Text.Feed.Query
import Text.Feed.Types
import Data.Maybe
import qualified Data.ByteString as B
import Network.URI (parseURI, uriToString)
getTitleAndUrl :: Item -> (Maybe String, Maybe String)
getTitleAndUrl item = (getItemTitle item, getItemLink item)
downloadUri :: (String,String) -> IO ()
downloadUri (title,link) = do
file <- get link
B.writeFile title file
where
get url = let uri = case parseURI url of
Nothing -> error $ "invalid uri" ++ url
Just u -> u in
simpleHTTP (defaultGETRequest_ uri) >>= getResponseBody
getTuples :: IO (Maybe [(Maybe String, Maybe String)])
getTuples = fmap (map getTitleAndUrl) <$> fmap (feedItems) <$> parseFeedString <$> (simpleHTTP (getRequest "http://index.hu/24ora/rss/") >>= getResponseBody)
我达到了这样的状态:我得到了一个包含元组的列表,其中包含名称和相应的链接。我有一个 downloadUri 函数,它可以正确地将给定链接下载到具有 rss 项目标题名称的文件。
我已经尝试修改 downloadUri
以使用 fmap
- 处理 (Maybe String,Maybe String)
- ing on get
和 writeFile
但严重失败。
如何将我的
downloadUri
函数应用于getTuples
函数的结果。我想实现以下主要功能main::IO()
main = 一些魔法咒语 donwloadUri 更多咒语 getTuples
getItemTitle
结果的字符编码被破坏,它将代码点放在重音字符的位置。 feed 是 utf8 编码的,我认为所有 haskell 字符串操作函数都默认为 utf8。我该如何解决这个问题?
编辑:
感谢您的帮助,我成功实现了我的主要功能和辅助功能。代码如下:
downloadUri :: (Maybe String,Maybe String) -> IO ()
downloadUri (Just title,Just link) = do
item <- get link
B.writeFile title item
where
get url = let uri = case parseURI url of
Nothing -> error $ "invalid uri" ++ url
Just u -> u in
simpleHTTP (defaultGETRequest_ uri) >>= getResponseBody
downloadUri _ = print "Somewhere something went Nothing"
getTuples :: IO (Maybe [(Maybe String, Maybe String)])
getTuples = fmap (map getTitleAndUrl) <$> fmap (feedItems) <$> parseFeedString <$> decodeString <$> (simpleHTTP (getRequest "http://index.hu/24ora/rss/") >>= getResponseBody)
downloadAllItems :: Maybe [(Maybe String, Maybe String)] -> IO ()
downloadAllItems (Just feedlist) = mapM_ downloadUri $ feedlist
downloadAllItems _ = error "feed does not get parsed"
main = getTuples >>= downloadAllItems
字符编码问题已部分解决,我将 decodeString
放在 feed 解析之前,以便文件得到正确命名。但如果我想打印出来,问题仍然发生。最小工作示例:
main = getTuples
最佳答案
听起来好像是也许
给你带来了麻烦。有很多方法可以处理 Maybe
值,以及一些有用的库函数,例如 fromMaybe
和 fromJust
。然而,最简单的方法是对 Maybe
值进行模式匹配。我们可以调整您的 downloadUri 函数以使用 Maybe
值。这是一个例子:
downloadUri :: (Maybe String, Maybe String) -> IO ()
downloadUri (Just title, Just link) = do
file <- get link
B.writeFile title file
where
get url = let uri = case parseURI url of
Nothing -> error $ "invalid uri" ++ url
Just u -> u in
simpleHTTP (defaultGETRequest_ uri) >>= getResponseBody
downloadUri _ = error "One of my parameters was Nothing".
或者您可以将标题默认为空白,在这种情况下,您可以将其插入到上一个示例中的最后一行之前:
downloadUri (Nothing, Just link) = downloadUri (Just "", Just link)
现在您唯一需要使用的也许
是应用于元组数组的外部。同样,我们可以进行模式匹配。编写这样的辅助函数可能是最清楚的:
downloadAllItems (Just ts) = ??? -- hint: try a `mapM`
downloadAllItems Nothing = ??? -- don't do anything, or report an error, or...
至于你的编码问题,我的猜测是:
- 您正在从非 UTF-8 编码的文件中读取信息,或者您的系统无法识别该文件是 UTF-8 编码的。
- 您读取的信息是正确的,但输出时会出现困惑。
为了帮助您解决这个问题,我需要查看完整的代码示例,其中显示了您如何读取信息以及如何输出信息。
关于haskell - Haskell 中的简单 RSS 下载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17038947/