2011-09-08 42 views
6

Wikipedia cung cấp liên kết (bên trái trên In/xuất) trên mỗi bài viết để tải xuống bài viết dưới dạng pdf. Tôi đã viết một kịch bản Haskell nhỏ đầu tiên nhận được liên kết Wikipedia và xuất kết nối hiển thị. Khi tôi đưa url hiển thị làm đầu vào, tôi nhận được các thẻ trống nhưng cùng một url trong trình duyệt cung cấp liên kết tải xuống.Tải xuống tệp pdf từ wikipedia

Ai đó có thể cho tôi biết cách giải quyết vấn đề này? Mã được định dạng trên 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

Đối với những người muốn tải pdf trực tiếp và không biết làm thế nào để làm điều đó, vui lòng tham khảo http: // www.youtube.com/watch?v=juBDM3fb-i0 –

Trả lời

5

Nếu bạn thử yêu cầu URL thông qua một số công cụ bên ngoài như wget, bạn sẽ thấy rằng Wikipedia không trực tiếp phục vụ trang kết quả. Nó thực sự trả về chuyển hướng 302 Moved Temporarily.

Khi nhập URL này vào trình duyệt, điều đó sẽ ổn, vì trình duyệt sẽ tự động theo chuyển hướng. Tuy nhiên, simpleHTTP sẽ không. simpleHTTP là, như tên cho thấy, khá đơn giản. Nó không xử lý những thứ như cookie, SSL hoặc chuyển hướng.

Thay vào đó, bạn sẽ muốn sử dụng mô-đun Network.Browser. Nó cung cấp quyền kiểm soát nhiều hơn đối với các yêu cầu được thực hiện như thế nào. Đặc biệt, chức năng setAllowRedirects sẽ làm cho nó tự động theo các chuyển hướng.

Dưới đây là một chức năng nhanh chóng và dơ bẩn để tải về một URL vào một String với sự hỗ trợ cho chuyển hướng:

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 
Các vấn đề liên quan