2011-09-08 103 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