haskell - Haskell 中的简单 RSS 下载器

标签 haskell utf-8 rss

昨天,我尝试在 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 getwriteFile 但严重失败。

  • 如何将我的 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 值,以及一些有用的库函数,例如 fromMaybefromJust。然而,最简单的方法是对 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...

至于你的编码问题,我的猜测是:

  1. 您正在从非 UTF-8 编码的文件中读取信息,或者您的系统无法识别该文件是 UTF-8 编码的。
  2. 您读取的信息是正确的,但输出时会出现困惑。

为了帮助您解决这个问题,我需要查看完整的代码示例,其中显示了您如何读取信息以及如何输出信息。

关于haskell - Haskell 中的简单 RSS 下载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17038947/

相关文章:

iOS 解析器分配断点

javascript - 解析 JSON 以获取 Google News Feed 中描述的干净、纯文本

mongodb - 访问函数不返回 Either Failure a

haskell - 堆栈空间溢出(可能与mapM有关)

haskell - 如何从外部代码确定数据的构造函数?

mysql - 为什么当我通过 phpMyAdmin 导入 SQL 数据库时导入没有完成

django - Django Elasticsearch AWS httplib UnicodeDecodeError

haskell - 在 Haskell 中实现 Iota

java - 找出小Tethe char的utf-8值

android - 如何等待截击响应完成它在 intentservice 中的工作?