0

我正在完成 Plutus Pioneer Lectures 的第一次迭代,从 coinmarketcap.com 获取汇率的第 6 课的代码返回 403 错误:

getExchangeRate = runReq defaultHttpConfig $ do
    v <- req
        GET
        (https "coinmarketcap.com" /: "currencies" /: "cardano")
        NoReqBody
        bsResponse
        mempty
    let priceRegex      = "priceValue___11gHJ\">\\$([\\.0-9]*)" :: ByteString
        (_, _, _, [bs]) = responseBody v =~ priceRegex :: (ByteString, ByteString, ByteString, [ByteString])
        d               = read $ unpack bs :: Double
        x               = round $ 1_000_000 * d
    liftIO $ putStrLn $ "queried exchange rate: " ++ show d
    return x 

如果我在 curl 中使用 -L 选项尝试相同的 url 来跟踪重定向,它会起作用:

curl -i -L 'https://coinmarketcap.com/currencies/cardano'

我能看到的唯一区别是 Haskell 代码的请求是HTTP/1.1,但是 curl 请求正在发送HTTP/2

我想更改 Haskell 库发送的 HTTP 版本,以检查这是否是问题所在。但是,我是 Haskell 的新手,所以我无法弄清楚 Haskell Network.HTTP.Req 模块是否可以设置 HTTP 版本。

有没有办法做到这一点?

TIA

4

1 回答 1

1

我相信 coinmarketcap.com 正在阻止未User-Agent指定标头的请求。你可以这样做:

getExchangeRate = runReq defaultHttpConfig $ do
    v <- req
        GET
        (https "coinmarketcap.com" /: "currencies" /: "cardano")
        NoReqBody
        bsResponse
        (header "User-Agent" "my-app/0.1.0.0")
    let priceRegex      = "priceValue___11gHJ\">\\$([\\.0-9]*)" :: ByteString
        (_, _, _, [bs]) = responseBody v =~ priceRegex :: (ByteString, ByteString, ByteString, [ByteString])
        d               = read $ unpack bs :: Double
        x               = round $ 1_000_000 * d
    liftIO $ putStrLn $ "queried exchange rate: " ++ show d
    return x 

使用此代码,请求可以正确完成,但我遇到了模式匹配错误。似乎priceValue___11gHJ正则表达式不再起作用。

于 2021-09-09T08:51:39.720 回答