6 Stimmen

pdf-Datei von wikipedia herunterladen

Wikipedia bietet einen Link (links auf Drucken/Exportieren) zu jedem Artikel, um den Artikel als PDF herunterzuladen. Ich habe ein kleines Haskell-Skript geschrieben, das zunächst den Wikipedia-Link abruft und den Rendering-Link ausgibt. Wenn ich die Rendering-URL als Eingabe eingebe, erhalte ich leere Tags, aber die gleiche URL im Browser bietet einen Download-Link.

Kann mir bitte jemand sagen, wie ich dieses Problem lösen kann? Formatierter Code auf 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

5voto

hammar Punkte 136080

Wenn Sie versuchen, die URL über ein externes Tool abzurufen, wie wget Sie werden sehen, dass Wikipedia die Ergebnisseite nicht direkt anzeigt. Sie gibt vielmehr eine 302 Moved Temporarily umleiten.

Wenn Sie diese URL in einen Browser eingeben, ist das kein Problem, da der Browser der Weiterleitung automatisch folgt. simpleHTTP wird jedoch nicht. simpleHTTP ist, wie der Name schon sagt, recht einfach. Es behandelt keine Dinge wie Cookies, SSL oder Weiterleitungen.

Sie sollten die Network.Browser Modul stattdessen. Es bietet viel mehr Kontrolle darüber, wie die Anfragen ausgeführt werden. Insbesondere kann das setAllowRedirects sorgt dafür, dass es automatisch Weiterleitungen folgt.

Hier ist eine schnelle und schmutzige Funktion zum Herunterladen einer URL in eine String mit Unterstützung für Weiterleitungen:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X