2011-09-08 68 views
6

维基百科在每篇文章中提供一个链接(打印/导出的左侧),以PDF格式下载文章。我编写了一个小的Haskell脚本,它首先获取Wikipedia链接并输出呈现链接。当我将渲染网址作为输入时,我得到空标记,但浏览器中的相同网址提供下载链接。从维基百科下载pdf文件

有人能告诉我如何解决这个问题吗?格式代码ideone

import Network.HTTP 
import Text.HTML.TagSoup 
import Data.Maybe 

parseHelp :: Tag String -> Maybe String 
parseHelp (TagOpen _ y) = if any (\(a , b) -> b == "Download a PDF version of this wiki page") y 
         then Just $ "http://en.wikipedia.org" ++ snd ( y !! 0) 
        else Nothing 


parse :: [ Tag String ] -> Maybe String 
parse [] = Nothing 
parse (x : xs) 
    | isTagOpen x = case parseHelp x of 
       Just s -> Just s 
       Nothing -> parse xs 
    | otherwise = parse xs 


main = do 
    x <- getLine 
    tags_1 <- fmap parseTags $ getResponseBody =<< simpleHTTP (getRequest x) --open url 
    let lst = head . sections (~== "<div class=portal id=p-coll-print_export>") $ tags_1 
     url = fromJust . parse $ lst --rendering url 
    putStrLn url 
    tags_2 <- fmap parseTags $ getResponseBody =<< simpleHTTP (getRequest url) 
    print tags_2 
+0

对于那些谁想要直接下载PDF和不知道如何做到这一点,请参阅HTTP:// www.youtube.com/watch?v=juBDM3fb-i0 –

回答

5

如果试图通过像wget一些外部工具请求的网址,你会看到,维基百科不直接服务了结果页面。它实际上会返回一个302 Moved Temporarily重定向。

在浏览器中输入此URL时,它会没事的,因为浏览器会自动执行重定向。然而,simpleHTTP不会。正如其名字所暗示的那样,相当简单。它不处理cookies,SSL或重定向等内容。

您需要改为使用Network.Browser模块。它对请求的完成方式提供了更多的控制。特别是,setAllowRedirects函数将使其自动遵循重定向。

下面是下载的URL为String与重定向支持快速和肮脏的功能:

import Network.Browser 

grabUrl :: String -> IO String 
grabUrl url = fmap (rspBody . snd) . browse $ do 
    -- Disable logging output 
    setErrHandler $ const (return()) 
    setOutHandler $ const (return()) 

    setAllowRedirects True 
    request $ getRequest url