Результат ответа на Haskell http не читается - PullRequest
5 голосов
/ 29 сентября 2011
import Network.URI
import Network.HTTP
import Network.Browser

get :: URI -> IO String
get uri = do
  let req = Request uri GET [] ""
  resp <- browse $ do
    setAllowRedirects True -- handle HTTP redirects
    request req
  return $ rspBody $ snd resp

main = do
  case parseURI "http://cn.bing.com/search?q=hello" of
    Nothing -> putStrLn "Invalid search"
    Just uri -> do
        body <- get uri
        writeFile "output.txt" body

Вот разница между выводом haskell и выводом curl

vimdiff

1 Ответ

8 голосов
/ 29 сентября 2011

Вероятно, здесь не рекомендуется использовать String в качестве промежуточного типа данных, поскольку это приведет к преобразованию символов как при чтении ответа HTTP, так и при записи в файл.Это может привести к повреждению, если эти преобразования не являются согласованными, как может показаться, что они здесь.

Поскольку вы просто хотите напрямую скопировать байты, лучше использовать ByteString.Я решил использовать ленивый ByteString здесь, чтобы его не нужно было загружать в память все сразу, но можно лениво перетекать в файл, как с String.

import Network.URI
import Network.HTTP
import Network.Browser
import qualified Data.ByteString.Lazy as L

get :: URI -> IO L.ByteString
get uri = do
  let req = Request uri GET [] L.empty
  resp <- browse $ do
    setAllowRedirects True -- handle HTTP redirects
    request req
  return $ rspBody $ snd resp

main = do
  case parseURI "http://cn.bing.com/search?q=hello" of
    Nothing -> putStrLn "Invalid search"
    Just uri -> do
        body <- get uri
        L.writeFile "output.txt" body

К счастью, функции в Network.Browser перегружены, так что изменение ленивых байтовых строк включает только изменение тела запроса на L.empty, замену writeFile на L.writeFile, а также изменение сигнатуры типа функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...