2011-09-08 16 views
6

Wikipedia proporciona un enlace (lado izquierdo en Imprimir/exportar) en cada artículo para descargar el artículo en formato pdf. Escribí un pequeño script de Haskell que primero obtiene el enlace de Wikipedia y muestra el enlace de representación. Cuando estoy dando la url de renderizado como entrada, obtengo etiquetas vacías pero la misma url en el navegador proporciona un enlace de descarga.Descargar el archivo pdf de la wikipedia

¿Podría alguien decirme cómo solucionar este problema? Código formateado en 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

Para aquellos que quieren descargar pdf directamente y no sé cómo hacerlo, consulte http: // www.youtube.com/watch?v=juBDM3fb-i0 –

Respuesta

5

Si intenta solicitar la URL a través de alguna herramienta externa como wget, verá que la Wikipedia no sirve a la página de resultados de forma directa. En realidad, devuelve un redireccionamiento 302 Moved Temporarily.

Al ingresar esta URL en un navegador, estará bien, ya que el navegador seguirá la redirección automáticamente. simpleHTTP, sin embargo, no lo hará. simpleHTTP es, como su nombre lo sugiere, bastante simple. No maneja cosas como cookies, SSL o redirecciones.

En su lugar, querrá utilizar el módulo Network.Browser. Ofrece mucho más control sobre cómo se realizan las solicitudes. En particular, la función setAllowRedirects hará que siga automáticamente las redirecciones.

Aquí está una función rápida y sucia para la descarga de una URL en un String con soporte para redirecciones:

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 
Cuestiones relacionadas