ybf

ybf


1.14okex网站汇率抓取代码参考

@Service @Slf4j public class OkexExchangePrice implements CoinPriceFetchService { @Value("#{'${okex.url}'.split(',')}") private List<String> okexUrlList;

private int index = 0;

private final BaseExchangeRateServiceImpl baseExchangeRateService;
private final ExchangeRateCheckService exchangeRateService;
private final CoinDisposeExchangePrice coinDisposeExchangePrice;
private final DisposeRateDataService disposeRateDataService;
private final ExchangeRateStatService exchangeRateStatService;

@Autowired
public OkexExchangePrice(BaseExchangeRateServiceImpl baseExchangeRateService
        , ExchangeRateCheckService exchangeRateService, CoinDisposeExchangePrice coinDisposeExchangePrice
        , DisposeRateDataService disposeRateDataService,ExchangeRateStatService exchangeRateStatService
) {
    this.baseExchangeRateService = baseExchangeRateService;
    this.exchangeRateService = exchangeRateService;
    this.coinDisposeExchangePrice = coinDisposeExchangePrice;
    this.disposeRateDataService=disposeRateDataService;
    this.exchangeRateStatService=exchangeRateStatService;
}

private static Map&lt;String, String&gt; buildHeader() {
    Map&lt;String, String&gt; headers = new HashMap&lt;&gt;();
    headers.put(&quot;accept&quot;, &quot;application/json&quot;);
    headers.put(&quot;:method&quot;, &quot;GET&quot;);
    headers.put(&quot;app-type&quot;, &quot;web&quot;);
    headers.put(&quot;accept-language&quot;, &quot;zh-CN,zh;q=0.9&quot;);
    headers.put(&quot;user-agent&quot;, &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36&quot;);
    headers.put(&quot;x-cdn&quot;, &quot;https://static.okex.com&quot;);
    return headers;
}

private static String buildParams(String sellOrBuy, String assetType, String currency, long start) {
    StringBuilder s = new StringBuilder(&quot;?t=&quot;);
    s.append(start);
    s.append(&quot;&amp;quoteCurrency=&quot;).append(currency);
    s.append(&quot;&amp;baseCurrency=&quot;).append(assetType);
    s.append(&quot;&amp;side=&quot;).append(sellOrBuy.equals(&quot;sell&quot;)?&quot;buy&quot;:&quot;sell&quot;);
    s.append(&quot;&amp;paymentMethod=all&amp;userType=all&amp;showTrade=false&quot;);
    return s.toString();
}

@Override
public void fetchPriceJsonAndSave() {
    //取卖一价
    getAndSavePriceInfo(AssetType.USDT, &quot;sell&quot;, &quot;CNY&quot;);
    //取买一价
    getAndSavePriceInfo(AssetType.USDT, &quot;buy&quot;, &quot;CNY&quot;);
    //取卖一价
    getAndSavePriceInfo(AssetType.BTC, &quot;sell&quot;, &quot;CNY&quot;);
    //取买一价
    getAndSavePriceInfo(AssetType.BTC, &quot;buy&quot;, &quot;CNY&quot;);
    //取卖一价
    getAndSavePriceInfo(AssetType.USDT, &quot;sell&quot;, &quot;USD&quot;);
    //取买一价
    getAndSavePriceInfo(AssetType.USDT, &quot;buy&quot;, &quot;USD&quot;);
}

private void getAndSavePriceInfo(AssetType assetType, String sellOrBuy, String currency) {
    long start = System.currentTimeMillis();
    Map&lt;String, String&gt; headers = buildHeader();

    String responseString;
    try {
        int size = okexUrlList.size();
        if (index &gt;= size) {
            index = 0;
        }
        /*https://www.okex.com/v3/c2c/tradingOrders/book?t=1605285545917&amp;quoteCurrency=CNY&amp;baseCurrency=BTC&amp;side=sell&amp;paymentMethod=all&amp;userType=all&amp;showTrade=false*/
        String url = okexUrlList.get(index++) + buildParams(sellOrBuy, assetType.getSymbol(), currency, start);
        log.info(&quot;Okex抓取url:{}&quot;, url);
        responseString = HttpClientUtils.getUseProxy(url, headers);
        /*log.info(&quot;获取Okex网{}币价信息:\n{}&quot;, assetType.getSymbol(), responseString);*/
    } catch (Exception e) {
        log.warn(&quot;获取Okex网{}币价信息失败:{}&quot;, assetType.getSymbol(), e.getMessage());
        responseString = e.getMessage();
    }
    long duration = System.currentTimeMillis() - start;
    /*即使没有获取到价格信息,也要记录一条空数据*/
    parseAndSave(sellOrBuy, responseString, assetType, currency,duration);
}

private void parseAndSave(String sellOrBuy, String responseString, AssetType assetType,String currency, long duration) {
    BigDecimal thePrice = null;
    Integer directionCode = null;
    ApiInfoEnum apiInfoEnum = null;
    apiInfoEnum = getApiInfoEnum(assetType, sellOrBuy, currency);
    if (StringUtils.isNotBlank(responseString)) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(responseString).getJSONObject(&quot;data&quot;);
            if (null != jsonObject) {
                if (&quot;buy&quot;.equals(sellOrBuy)) {
                    log.info(&quot;Okx抓取到的{}买一价为:{}&quot;, assetType, thePrice);
                    directionCode = BUY_DIRECTION;
                }

                if (&quot;sell&quot;.equals(sellOrBuy)) {
                    log.info(&quot;Okx抓取到的{}卖一价为:{}&quot;, assetType, thePrice);
                    directionCode = SELL_DIRECTION;
                }
                JSONArray jsonArr = jsonObject.getJSONArray(sellOrBuy.equals(&quot;sell&quot;)?&quot;buy&quot;:&quot;sell&quot;);
                if(Objects.nonNull(jsonArr)&amp;&amp;jsonArr.size()&gt;0){
                    //获取前20条挂单数据
                    if(AssetType.USDT.equals(assetType)&amp;&amp;currency.equals(AssetType.CNY.getSymbol())){
                        List&lt;CommonExchageResp&gt; exchanges = jsonArr.stream().map(js -&gt; {
                            CommonExchageResp commonExchageResp = new CommonExchageResp();
                            commonExchageResp.setPrice(new BigDecimal(((JSONObject) js).getString(&quot;price&quot;)));
                            commonExchageResp.setPendingOrderVolume(new BigDecimal(((JSONObject) js).getString(&quot;availableAmount&quot;)));
                            commonExchageResp.setDownLimit(new BigDecimal(((JSONObject) js).getString(&quot;quoteMinAmountPerOrder&quot;)));
                            commonExchageResp.setUpLimit(new BigDecimal(((JSONObject) js).getString(&quot;quoteMaxAmountPerOrder&quot;)));
                            commonExchageResp.setTradingVolume(Integer.parseInt(((JSONObject) js).getString(&quot;completedOrderQuantity&quot;)));
                            commonExchageResp.setCloseRate(new BigDecimal(((JSONObject) js).getString(&quot;completedRate&quot;)));
                            commonExchageResp.setPriceUnit(AssetType.CNY.getSymbol());
                            return commonExchageResp;
                        }).limit(20).collect(Collectors.toList());
                        //获取有效汇率
                        CommonExchageResp filterExchangeRate = disposeRateDataService
                                .disposeRateData(PatformKeyEnum.OKX,TradeDirectionEnum.valueOf(directionCode), exchanges);
                        log.info(&quot;【Okx】汇率过滤,{},原始汇率条数:{},有效汇率:{}&quot;,
                                apiInfoEnum.getDescription(), exchanges.size(), JSON.toJSONString(filterExchangeRate));
                        if(Objects.nonNull(filterExchangeRate)){
                            thePrice=filterExchangeRate.getPrice();
                        }
                        //保存第一条和第六条数据价格,以便运营进行分析
                        exchangeRateStatService.saveExchangeRateStat(sellOrBuy,RateSourceEnum.OKEX.getMsg(),exchanges,thePrice);
                    }else{
                        JSONObject jsonObj = jsonArr.getJSONObject(0);
                        thePrice = new BigDecimal(jsonObj.getString(&quot;price&quot;));
                    }
                }
            }
            log.info(&quot;Okx抓取到的{}价格为:{}&quot;, assetType, thePrice);
        } catch (Exception e) {
            log.warn(&quot;Okx数据格式异常:{}&quot;, e.getMessage());
        }
    }
    try {
        BaseExchangeRateHistoryDTO baseExchangeRateHistoryDTO = new BaseExchangeRateHistoryDTO();
        baseExchangeRateHistoryDTO.setCoinType(assetType);

        if(AssetType.USDT.equals(assetType)){
            if(AssetType.USD.getSymbol().equals(currency)){
                baseExchangeRateHistoryDTO.setPriceTrading(RateTradingEnum.USD_USDT);
                baseExchangeRateHistoryDTO.setPriceUnit(AssetType.USD);
            }else{
                baseExchangeRateHistoryDTO.setPriceTrading(RateTradingEnum.CNY_USDT);
                baseExchangeRateHistoryDTO.setPriceUnit(AssetType.CNY);
            }
        }
        if(AssetType.BTC.equals(assetType)){
            baseExchangeRateHistoryDTO.setPriceTrading(RateTradingEnum.CNY_BTC);
            baseExchangeRateHistoryDTO.setPriceUnit(AssetType.CNY);
        }
        baseExchangeRateHistoryDTO.setDuration(duration);
        baseExchangeRateHistoryDTO.setResponse(responseString);
        baseExchangeRateHistoryDTO.setPrice(thePrice);
        baseExchangeRateHistoryDTO.setDirection(directionCode);
        baseExchangeRateHistoryDTO.setApiInfo(apiInfoEnum);
        baseExchangeRateHistoryDTO.setApiSource(RateSourceEnum.OKEX);
        log.info(&quot;Okex抓取baseExchangeRateHistoryDTO: {}&quot;, JacksonUtils.desJson(baseExchangeRateHistoryDTO));
        baseExchangeRateService.mergeBaseExchangeRate(baseExchangeRateHistoryDTO, true);

        //转换USD-CNY
        if(AssetType.USDT.equals(assetType)&amp;&amp;AssetType.USD.getSymbol().equals(currency)){
            coinDisposeExchangePrice.fetchPriceJsonAndSave(AssetType.USD.getSymbol(), RateSourceEnum.OKEX.getMsg());
        }
    } catch (Exception e) {
        log.error(&quot;Okex汇率更新失败:{}&quot;, e.getMessage());
    }
}

private void checkPrice(AssetType assetType, BigDecimal thePrice, ApiInfoEnum apiInfoEnum, Integer sellDirection) {
    exchangeRateService.checkPrice(assetType, thePrice);
}

private ApiInfoEnum getApiInfoEnum(AssetType assetType, String sellOrBuy, String currency) {
    ApiInfoEnum apiInfoEnum = null;
    if (&quot;buy&quot;.equals(sellOrBuy)) {
        if (AssetType.USDT.equals(assetType)) {
            if(AssetType.CNY.getSymbol().equals(currency)){
                apiInfoEnum = OKEX_OTC_USDT_FIRST_BUY_PRICE;
            }
            if(AssetType.USD.getSymbol().equals(currency)){
                apiInfoEnum = OKEX_USD_USDT_FIRST_BUY_PRICE;
            }
        } else if (AssetType.BTC.equals(assetType)) {
            apiInfoEnum = OKEX_OTC_BTC_FIRST_BUY_PRICE;
        }
    } else {
        if (AssetType.USDT.equals(assetType)) {
            if(AssetType.CNY.getSymbol().equals(currency)){
                apiInfoEnum = OKEX_OTC_USDT_FIRST_SELL_PRICE;
            }
            if(AssetType.USD.getSymbol().equals(currency)){
                apiInfoEnum = OKEX_USD_USDT_FIRST_SELL_PRICE;
            }
        } else if (AssetType.BTC.equals(assetType)) {
            apiInfoEnum = OKEX_OTC_BTC_FIRST_SELL_PRICE;
        }
    }
    return apiInfoEnum;
}

public static void main(String[] args) {
    long now = System.currentTimeMillis();
    /*
     * https://www.okex.com/v3/c2c/tradingOrders/book?
     * 会员出售数币时参数,价格由高到低:5.02到5.00,第一条即为okex网站买入一价
     * t=1605444088527&amp;quoteCurrency=CNY&amp;baseCurrency=USDT&amp;side=buy&amp;paymentMethod=all&amp;userType=all&amp;showTrade=false&amp;urlId=1
     *会员购买数币时参数,价格由低到高5.04到5.98,第一条即为okex网站卖出一价
     * t=1605444186022&amp;quoteCurrency=CNY&amp;baseCurrency=USDT&amp;side=sell&amp;paymentMethod=all&amp;userType=all&amp;showTrade=false
     * */
    try {
        Map&lt;String, String&gt; headers = buildHeader();
        String url = null;//&quot;https://www.okx.com/v3/c2c/tradingOrders/books?t=&quot; + now + &quot;&amp;quoteCurrency=USD&amp;baseCurrency=USDT&amp;side=sell&amp;paymentMethod=all&amp;userType=all&quot;;
                url=&quot;https://www.okx.com/v3/c2c/tradingOrders/books?t=1645793891626&amp;quoteCurrency=CNY&amp;baseCurrency=USDT&amp;side=sell&amp;paymentMethod=all&amp;userType=all&amp;showTrade=false&amp;receivingAds=false&amp;showFollow=false&amp;showAlreadyTraded=false&amp;isAbleFilter=false&quot;;

// String result = HttpClientUtils.getUseProxy(url, headers);

        String responseString = HttpClientUtils.get(url);
        System.out.println(responseString);
        JSONObject jsonObject = JSONObject.parseObject(responseString).getJSONObject(&quot;data&quot;);
        JSONArray jsonArr = jsonObject.getJSONArray(&quot;buy&quot;.equals(&quot;sell&quot;)?&quot;buy&quot;:&quot;sell&quot;);
        jsonArr.stream().map(js-&gt;{
            System.out.println(
             &quot; 单价:&quot;+((JSONObject) js).getString(&quot;price&quot;)
            +&quot; 数量:&quot;+((JSONObject) js).get(&quot;availableAmount&quot;)
            +&quot; 限额:&quot;+((JSONObject) js).getString(&quot;quoteMinAmountPerOrder&quot;)+&quot;~&quot;+((JSONObject) js).getString(&quot;quoteMaxAmountPerOrder&quot;)
            +&quot; 成交量:&quot;+((JSONObject) js).getString(&quot;completedOrderQuantity&quot;)
            +&quot; 成交率:&quot;+((JSONObject) js).getString(&quot;completedRate&quot;)
            );
            return null;
        }).limit(20).collect(Collectors.toList());
    } catch (Exception e) {
        log.error(&quot;获取Okex币价信息失败:{}&quot;, e.getMessage());
    }
}

}

页面列表

ITEM_HTML