1. <small id="7qjag"></small>
    <small id="7qjag"></small>

  2. <p id="7qjag"></p>

    麻豆精品一卡二卡三卡 ,国产成人久久av免费高潮,热久久视久久精品18,成人无码看片在线观看免费 ,玩弄少妇肉体到高潮动态图,国产精品久久久久久影视不卡,国产成人无码免费看片软件,免费人成激情视频在线观看冫

    今頭條!(Java)記一次通過API遞歸分頁“爬取”網頁數據的開發經歷

    來源: 博客園2023-05-30 12:33:40
      

    前言

    在最近的互聯網項目開發中,需要獲取用戶的訪問ip信息進行統計的需求,用戶的訪問方式可能會從微信內置瀏覽器、Windows瀏覽器等方式對產品進行訪問。

    當然,獲取這些關于ip的信息是合法的。但是,這些ip信息我們采用了其它第三方的服務來記錄,并不在我們的數據庫中。

    這些ip信息是分組存放的,且每個分組都都是分頁(1頁10條)存放的,如果一次性訪問大量的數據,API很有可能會報錯。


    (資料圖)

    怎樣通過HTTP的方式去獲取到信息,并且模擬瀏覽器每頁每頁獲取10條的信息,且持久到數據庫中,就成了當下亟需解決的問題。

    通過以上的分析,可以有大致以下思路:

    1、拿到該網頁http請求的url地址,同時獲取到調用該網頁信息的參數(如:header、param等);

    2、針對分頁參數進行設計,由于需要不斷地訪問同一個接口,所以可以用循環+遞歸的方式來調用;

    3、將http接口的信息進行解析,同時保證一定的訪問頻率(大部分外部http請求都會有訪問頻率限制)讓返回的數據準確;

    4、整理和轉化數據,按照一定的條件,批量持久化到數據庫中。

    一、模擬http請求

    我們除了在項目自己寫API接口提供服務訪問外,很多時候也會使用到外部服務的API接口,通過調用這些API來返回我們需要的數據。

    如:

    釘釘開放平臺https://open.dingtalk.com/document/orgapp/user-information-creation、

    微信開放平臺https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN等等進行開發。

    這里分享一下從普通網頁獲取http接口url的方式,從而達到模擬http請求的效果:以谷歌chrome瀏覽器為例,打開調式模式,根據下圖步驟:尤其注意使用Fetch/XHR,右鍵該url—>copy—>copy as cURL(bash):隨后粘貼到Postman中,模擬http請求:粘貼的同時,還會自動帶上header參數(以下這4個參數比較重要,尤其是cookie):這樣,就可以訪問到所需的數據了,并且數據是json格式化的,這便于我們下一步的數據解析。

    二、遞歸+循環設計

    有幾個要點需要注意:1、分內外兩層,內外都需要獲取數據,即外層獲取的數據是內層所需要的;2、每頁按照10條數據來返回,直到該請求沒有數據,則訪問下一個請求;3、遞歸獲取當前請求的數據,注意頁數的增加和遞歸終止條件。廢話不多說,直接上代碼:

    點擊查看代碼
    public boolean getIpPoolOriginLinksInfo(HashMap commonPageMap, HashMap headersMap,String charset){        //接口調用頻率限制        check(commonAPICheckData);        String linkUrl = "https://xxx.xxx.com/api/v1/xxx/xxx";        HashMap linkParamsMap = new HashMap<>();        linkParamsMap.put("page",commonPageMap.get("page"));        linkParamsMap.put("size",commonPageMap.get("size"));        String httpLinkResponse = null;        //封裝好的工具類,可以直接用apache的原生httpClient,也可以用Hutool的工具包        httpLinkResponse = IpPoolHttpUtils.doGet(linkUrl,linkParamsMap,headersMap,charset);        JSONObject linkJson = null;        JSONArray linkArray = null;        linkJson = JSON.parseObject(httpLinkResponse).getJSONObject("data");        linkArray = linkJson.getJSONArray("resultList");        if (linkArray != null){            //遞歸計數            if (!commonPageMap.get("page").toString().equals("1")){                commonPageMap.put("page","1");            }            // 每10條urlId,逐一遍歷            for (Object linkObj : linkJson.getJSONArray("resultList")) {                JSONObject info = JSON.parseObject(linkObj.toString());                String urlId = info.getString("urlId");                // 獲取到的每個urlId,根據urlId去獲取ip信息(即內層的業務邏輯,我這里忽略,本質就是拿這里的參數傳到內層的方法中去)                boolean flag = getIpPoolOriginRecords(urlId, commonPageMap, headersMap, charset);                if (!flag){                    break;                }            }            Integer page = Integer.parseInt(linkParamsMap.get("page").toString());            if (page <= Math.ceil(Integer.parseInt(linkJson.getString("total"))/10)){                Integer newPage = Integer.parseInt(linkParamsMap.get("page").toString()) + 1;                linkParamsMap.put("page", Integer.toString(newPage));                // 遞歸分頁拉取                getIpPoolOriginLinksInfo(linkParamsMap,headersMap,charset);            }            else {                return true;            }        }        return true;    }

    三、解析數據(調用頻率限制)

    一般來說,調用外部API接口會有調用頻率的限制,即一段時間內不允許頻繁請求接口,否則會返回報錯,或者禁止調用。基于這樣的限制,我們可以簡單設計一個接口校驗頻率的方法,防止請求的頻率太快。廢話不多說,代碼如下:

    點擊查看代碼
    /**     * 調用頻率校驗,按照分鐘為單位校驗     * @param commonAPICheckData     */    private void check(CommonAPICheckData commonAPICheckData){        int minuteCount = commonAPICheckData.getMinuteCount();        try {            if (minuteCount < 2){                //接近頻率限制時,休眠2秒                Thread.sleep(2000);            }else {                commonAPICheckData.setMinuteCount(minuteCount-1);            }        } catch (InterruptedException e) {            throw new RuntimeException("-------外部API調用頻率錯誤!--------");        }    }
    CommonAPICheckData類代碼:
    點擊查看代碼
    @Datapublic class CommonAPICheckData {    /**     * 每秒調用次數計數器,限制頻率:每秒鐘2次     */    private int secondCount = 3;    /**     * 每分鐘調用次數計數器,頻率限制:每分鐘100次     */    private int minuteCount = 100;}

    四、數據持久化

    爬出來的數據我這里是按照一條一條入庫的,當然也可以按照批次進行batch的方式入庫:

    點擊查看代碼
    /**   * 數據持久化   * @param commonIpPool   */    private boolean getIpPoolDetails(CommonIpPool commonIpPool){        try {            //list元素去重,ip字段唯一索引            commonIpPoolService.insert(commonIpPool);        } catch (Exception e) {            if (e instanceof DuplicateKeyException){                return true;            }            throw new RuntimeException(e.getMessage());        }        return true;    }

    五、小結

    其實,爬取數據的時候我們會遇到各種各樣的場景,這次分享的主要是分頁遞歸的相關思路。有的時候,如果網頁做了防爬的功能,比如在header上加簽、訪問前進行滑動圖片校驗、在cookie上做加密等等,之后有時間還會接著分享。代碼比較粗糙,如果大家有其它建議,歡迎討論。如有錯誤,還望大家指正。

    關鍵詞:

    責任編輯:sdnew003

    相關新聞

    版權與免責聲明:

    1 本網注明“來源:×××”(非商業周刊網)的作品,均轉載自其它媒體,轉載目的在于傳遞更多信息,并不代表本網贊同其觀點和對其真實性負責,本網不承擔此類稿件侵權行為的連帶責任。

    2 在本網的新聞頁面或BBS上進行跟帖或發表言論者,文責自負。

    3 相關信息并未經過本網站證實,不對您構成任何投資建議,據此操作,風險自擔。

    4 如涉及作品內容、版權等其它問題,請在30日內同本網聯系。

    主站蜘蛛池模板: 一二三四视频社区在线| 99久久久无码国产麻豆| 亚洲欧美日韩国产成人一区| 韩国的无码av看免费大片在线| 中文字幕日韩人妻不卡一区| 少妇午夜福利一区二区| 欧洲美熟女乱av亚洲一区| 欧美成人看片一区二区| 亚洲全国最大的人成网站| 久久国产色av免费看| 亚洲色无码一区二区三区| 精品国产va久久久久久久冰| 久久天天躁狠狠躁夜夜爽| 无码免费伦费影视在线观看 | 亚洲色无码播放亚洲成av| 日本少妇被黑人猛cao| 在线播放亚洲人成电影| 无遮挡啪啪摇乳动态图gif| 鲁鲁网亚洲站内射污| 精品精品国产欧美在线小说区| 国内精品自产拍在线观看 | 无码免费伦费影视在线观看| 女人高潮内射99精品| 欧美乱妇高清无乱码| 国产女精品视频网站免费| 精品无人区乱码1区2区3区在线| 热久久美女精品天天吊色| 亚洲成a v人片在线观看| 国产精品a久久777777| 亚洲a∨天堂男人无码| 久久久久久曰本av免费免费| 国产日产欧洲无码视频无遮挡 | 中文字幕无码肉感爆乳在线| 99精品热这里只有精品 | 国产亚洲精品久久久久久国| 日欧一片内射va在线影院| 久久香蕉国产线看观看怡红院妓院| 亚洲妇女无套内射精| 国产又爽又刺激的视频| 人人妻人人澡人人爽超污| 国产私拍福利精品视频|