麻豆精品一卡二卡三卡 ,国产成人久久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日內同本網聯系。

主站蜘蛛池模板: 亚洲国产精品无码久久98| 韩国的无码av看免费大片在线| 久久丫免费无码一区二区| 久久丫免费无码一区二区 | 免费午夜无码片在线观看影院| 亚洲欧美v国产一区二区| 国产欧美国日产在线播放| 亚洲全国最大的人成网站| 亚洲国产精品无码久久98| 五月天国产成人av免费观看| 97se狼狼狼狼狼亚洲网| 欧美人成视频在线视频| 久久精品国产一区二区无码| 亚洲综合无码一区二区三区不卡| 国产日产欧洲无码视频无遮挡 | 国产精品宾馆在线精品酒店 | 四虎影库久免费视频| 2020国产成人精品视频| 国产偷国产偷亚洲清高孕妇| 色婷婷五月综合亚洲小说| 欧美丰满熟妇xxxx| 一本久道中文无码字幕av| 无码日韩av一区二区三区| 亚洲精品久久久久久久久av无码| 成年无码动漫av片在线观看羞羞 | 人妻无码人妻有码中文字幕在线| 亚洲色大成网站www永久男同| 亚洲午夜福利精品久久| 精品国产综合区久久久久久| 国产日产欧产精品精品首页| 无遮挡啪啪摇乳动态图gif| 欧美品无码一区二区三区在线蜜桃| 国产99久久亚洲综合精品西瓜tv| 国内精品久久久久伊人av| 妺妺窝人体色www在线小说| 国产偷国产偷亚洲清高网站| 国产精品久久久久久熟妇吹潮软件| 插插插精品亚洲一区| 中文字幕日韩人妻不卡一区| 亚洲精品字幕| 九九热久久只有精品2|