博客 / 詳情

返回

python requests 爬取nexus庫依賴包數據

前言

由於nexus庫自帶API沒有輸出依賴包對應的創建時間(blobCreated)、上傳時間(blobUpdated),為方便管理依賴包只好從頁面返回的數據進行爬取(可能使用nexus-cli可以獲取,但是沒有細究這個方法)

思路

我這邊使用的nexus庫版本為 3.19.1-01,下面是在nexus庫API接口信息中可以查詢到關於依賴包信息的接口 /v1/components
image.png
該版本輸出的信息中只包含一般的 group、name、downloadUrl、repository等消息,沒有上傳時間相關的信息,但是在Browse 中可以查詢到相關的信息
image.png
通過瀏覽器開發工具可以查詢到,該信息來自
/service/extdirect 這個請求地址
image.png
image.png

根據接口請求負載可以看到,該接口需要傳入兩個參數
image.png
分別是repo地址以及一個id參數,仔細研究之後發現該id與nexus 自帶API(/v1/components)輸出的id並非一樣,而是來自同一個請求地址不同action的id名為 assetId
image.png
image.png
而這個請求需要傳入的參數分別是repo地址以及node信息,node信息可以通過'group'+'name'+'version'信息獲取。
那麼查詢到這一步思路就形成閉環了,整體思路如下:
通過nexus庫自帶API接口分別獲取:'group'+'name'+'version' 信息,組合成node信息,進而獲取到assetId信息,通過assetId信息獲取對應的依賴包詳細信息。
既然思路清晰了,那就開始備菜做飯(敲代碼調試)吧~

實現

獲取node節點信息 AKA 'group'+'name'+'version'信息

nexus_url = 'http://192.168.1.1:8081/'            #nexus庫地址
nexus_username = 'admin'                        #nexus賬號
nexus_password = 'admin123'                  #nexus密碼
repository = ['aliyun','maven-releases']              #nexus庫 repo地址
names = []
groups = []
versions = []
downloadUrls = []   #這裏順便獲取下載地址,沒太大用處可以忽略
asset_ids = []
def components_api(repository):     #請求components接口獲取依賴包包基本信息
    print('running components_api\t'+repository)
    #請求參數
    query_params = {
        'repository' : repository,   #傳入的repo信息
        'extension' : 'jar'         #依賴包類型
    }
    #請求API接口
    response = requests.get(
        nexus_url + '/service/rest/v1/components',
        params=query_params,
        auth=(nexus_username, nexus_password)   #API接口需要鑑權
    )
    #判斷接口狀態
    if response.status_code != 200:
        print('獲取依賴項信息失敗,狀態碼:{}'.format(response.status_code))
        print(response.content)
        exit()
    #將接口返回數據轉化為json格式用於處理
    response_data = response.json()
    # print(response_data)
    global name,group,version,downloadUrl
    for items in response_data['items']:
        name = format(items['name'])
        group = format(items['group'])
        version = format(items['version'])
        names.append(name)
        groups.append(group)
        versions.append(version)
        for asset in items['assets']:
            if asset['path'].endswith('.jar'):
                downloadUrl = format(asset['downloadUrl'])
                downloadUrls.append(downloadUrl)
    #執行時間        
    end = datetime.datetime.now()   
    print('components_api totally time is ' , end - start)

根據node信息獲取assetId

headers = {     #請求頭信息 nexus庫,cookie信息及token信息根據nexus庫賬號獲取
        'X-Requested-With': 'XMLHttpRequest',
        'X-Nexus-UI': 'true',
        'NX-ANTI-CSRF-TOKEN': '0.1427667210133794',
        'Content-Type': 'application/json',
        'Origin': nexus_url,
        'Referer': nexus_url,
        'Cookie': 'NX-ANTI-CSRF-TOKEN=0.1427667210133794; NXSESSIONID=9b2057c6-a456-4f94-85d7-90dcb07eb9e6'
    }
random_number = random.randint(50, 120)     #添加一個隨機數用於接口操作的tid
def get_nodeinfo(repository):             #根據components_api獲取的信息拼接獲得node路徑及asset_id
    print('get_nodeinfo\t'+repository)
    api_url = nexus_url + "/service/extdirect"
    for i in range(len(names)):
        Groups = [group.replace('.', '/') for group in groups]      #將groups中的‘.’轉換為‘/’
        node = Groups[i]+'/'+names[i]+'/'+versions[i]
        payload = json.dumps({
            "action": "coreui_Browse",
            "method": "read",
            "data": [{
            "repositoryName" : repository,
            "node": str(node)
            }],
            "type": "rpc",
            "tid": random_number
        })
        response = requests.request("POST", api_url, headers=headers, data=payload)
        if response.status_code != 200:     #判斷接口狀態
            print('獲取依賴項信息失敗,狀態碼:{}'.format(response.status_code))
            print(response.content)
            exit()
        response_data = response.json()
        global asset_ids
        for item in response_data['result']['data']:    #根據接口返回數據獲取assetid
            if item['text'].endswith('.jar'):
                asset_ids.append(item['assetId'])   #將API數據中的assetId存入變量asset_ids
    #執行時間
    end = datetime.datetime.now()
    print('get_nodeinfo totally time is ' , end - start)

根據assetId獲取依賴包詳細信息

INFO_NAME = []
INFO_REPO = []
INFO_CTIME = []
INFO_UTIME = []
INFO_DURL = []
INFO_GID = []
INFO_AID = []
INFO_VERSION = []
def get_assetid_info(repository):         #通過assetid獲取jar具體信息包括上傳時間及創建時間
    api_url = nexus_url + "/service/extdirect"
    for i in range(len(asset_ids)):
        aid = asset_ids[i]
        payload = json.dumps({
            "action": "coreui_Component",
            "method": "readAsset",
            "data": [
                aid,
                repository
            ],
            "type": "rpc",
            "tid": random_number
        })
        response = requests.request("POST", api_url, headers=headers, data=payload)
        global INFO_NAME,INFO_REPO,INFO_CTIME,INFO_UTIME,INFO_DURL,INFO_GID,INFO_AID,INFO_VERSION
        response_data = response.json()
        if response.status_code != 200:
            print('get_assetid_info 獲取依賴項信息失敗,狀態碼:{}'.format(response.status_code))
        if response_data['result']['success'] != True:
            print('get_assetid_info 獲取依賴項信息失敗,狀態碼:{}'.format(response.status_code))
        else:
            item = response_data['result']['data']
            durls = nexus_url+'/repository/'+repository+'/'+item['name']
            #輸出信息
            print('包名:'+item['name'],'\n'+ '所在repo:',item['repositoryName'],'\n'+'創建時間:',item['blobCreated'],'\n'+'更新時間:',item['blobUpdated'],'\n'+'下載地址:',durls)
            #將信息添加到集合用於後續處理入庫
            INFO_NAME.append(item['name'])
            INFO_REPO.append(item['repositoryName'])
            INFO_CTIME.append(item['blobCreated'])
            INFO_UTIME.append(item['blobUpdated'])
            INFO_DURL.append(durls)
            INFO_GID.append(item['attributes']['maven2']['groupId'])
            INFO_AID.append(item['attributes']['maven2']['artifactId'])
            INFO_VERSION.append(item['attributes']['maven2']['version'])
    #執行時間
    end = datetime.datetime.now()
    print('get_assetid_info totally time is ' ,end - start)

效果

執行效果:
image.png

結尾

後來發現nexus庫在 3.37.3-02 往後的版本(或許稍微往前的版本也有)中API接口已經有相關的時間輸出了
image.png
但是由於各種原因沒法進行升級操作,只好出此下策進行爬取信息,希望能幫助到有需要的人吧~
感謝看到最後~拜拜~

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.