{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Client
import Text.XML.HXT.Core
-- 代理信息
proxyHost = "www.duoip.cn"
proxyPort = 8000
-- 请求函数
request :: MonadIO m => ProxyInfo -> String -> m String
request proxy (uri ++ query) = do
let proxyURL = "http://" ++ proxyHost ++ ":" ++ show proxyPort ++ uri
let req = parseURI uri
let proxy = Proxy { proxyHost = proxyHost, proxyPort = proxyPort }
res <- liftIO $ curlPost req proxyURL
return (takeWhile (/= '\n') (T.pack (BS.unpack res)))
-- 解析HTML函数
parseHTML :: MonadIO m => String -> m [(String, String)]
parseHTML html = do
doc <- parseHTMLDoc html
let nodes = findClass "hotel-name" doc // findClass "hotel-address" doc
return $ mapMaybe (\node -> (getAttrValue "class" node, getInnerXML node)) nodes
-- 主函数
main :: IO ()
main = do
let proxy = Proxy { proxyHost = proxyHost, proxyPort = proxyPort }
html <- request proxy "https://booking.com/hotels-gb-lon-1.xml"
let hotels = parseHTML html
putStrLn $ "Found " ++ show (length hotels) ++ " hotels:"
for_ hotels $ \(name, address) -> putStrLn $ " - " ++ name ++ ": " ++ address
这个程序首先定义了一个request
函数,它接受一个代理信息和一个URL,然后使用curlPost
函数进行POST请求。然后定义了一个parseHTML
函数,它接受一个HTML字符串,然后使用parseHTMLDoc
函数解析HTML文档,然后查找所有类名为"hotel-name"和"hotel-address"的节点,并返回它们的名称和地址。
最后,main
函数首先获取代理信息,然后使用request
函数获取Booking的酒店数据,然后使用parseHTML
函数解析HTML数据,然后打印出找到的酒店数量和信息。
注意:这个程序只是一个示例,实际的爬虫程序需要根据具体的需求进行修改和扩展。