2011-09-08 17 views
6

Wikipedia fornisce un link (lato sinistro su Stampa/esportazione) su ogni articolo per scaricare l'articolo in formato pdf. Ho scritto un piccolo script Haskell che prima ottiene il link di Wikipedia e mostra il link di rendering. Quando sto dando l'url di rendering come input, ricevo tag vuoti ma lo stesso URL nel browser fornisce il link per il download.Scarica il file pdf da wikipedia

Qualcuno potrebbe dirmi come risolvere questo problema? Codice formattato su 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

Per coloro che desiderano scaricare direttamente in pdf e non so come fare, consulta http: // www.youtube.com/watch?v=juBDM3fb-i0 –

risposta

5

Se si tenta richiedendo l'URL attraverso qualche strumento esterno come wget, vedrete che Wikipedia non serve la pagina dei risultati direttamente. In realtà restituisce un reindirizzamento 302 Moved Temporarily.

Quando si inserisce questo URL in un browser, andrà bene, in quanto il browser seguirà automaticamente il reindirizzamento. simpleHTTP, tuttavia, non lo farà. simpleHTTP è, come suggerisce il nome, piuttosto semplice. Non gestisce cose come cookie, SSL o reindirizzamenti.

Vorrete utilizzare il modulo Network.Browser. Offre molto più controllo su come vengono fatte le richieste. In particolare, la funzione setAllowRedirects farà in modo che segua automaticamente i reindirizzamenti.

Ecco una funzione rapido e sporco per il download di un URL in un String con supporto per i reindirizzamenti:

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