huangyifan 1 жил өмнө
parent
commit
933e90cbfe

+ 281 - 0
sync_amz_data/public/SP_SB_SD_jsonDeal.py

@@ -0,0 +1,281 @@
+from adstoken import Ads_Api_Token
+import requests
+import datetime,time
+import pandas as pd
+import numpy as np
+
+access_tokenapi = Ads_Api_Token(shop_name='ZosiDirect', profileId='3006125408623189')
+access_token = access_tokenapi._get_access_token()
+
+def time_stamp_convert(df,segment:list):
+    for time_column in segment:
+        df[time_column] = pd.to_datetime(df[time_column]*1000000)
+    return df
+
+def placement_segmentsplit(df,segment):
+    df[segment] = df[segment].astype("string")
+    df[segment+str("_percentage")] = df[segment].str.extract("'percentage':.+([\d\.]{1,}),").astype('float32')
+    df[segment+str("_placement")] = df[segment].str.extract("'placement':.+'(.+)'")
+    df.replace(['nan','Nan','NaN'],np.nan,inplace=True)
+    df.drop(columns=[segment],inplace=True)
+    return df
+
+def columnsName_modify(df):
+    df.columns = [i.replace(".","_") for i in df.columns]
+    return df
+
+def get_profilio_info(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + token}
+
+    url_ = "https://advertising-api.amazon.com/v2/portfolios/extended"  # V3版本
+    req_time = 0
+    while (req_time != 3):
+        req_time += 1
+        res = requests.get(url_, headers=header)  # V3版本为post请求
+        if res.status_code not in [200, 207]:
+            time.sleep(3)
+        else:
+            return res.json()
+    return res.text
+# list_portfolio = get_profilio_info(access_token)
+# df_portfolio = pd.json_normalize(list_portfolio)
+# columnsName_modify(df_portfolio)
+
+def get_campaign_info_SP(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + token,
+              'Content-Type': 'application/vnd.spCampaign.v3+json',
+              'Accept': """application/vnd.spCampaign.v3+json"""}
+
+    url_ = "https://advertising-api.amazon.com/sp/campaigns/list"  # V3版本
+    req_time = 0
+    while (req_time != 3):
+        req_time += 1
+        res = requests.post(url_, headers=header)  # V3版本为post请求
+        print(res.status_code)
+        if res.status_code not in [200, 207]:
+            time.sleep(3)
+        else:
+            return res.json()
+    return res.text
+
+# list_campaign_SP = get_campaign_info_SP(access_token)
+# df_campaign = pd.json_normalize(list_campaign_SP['campaigns'])
+# df_campaign = placement_segmentsplit(df_campaign,"dynamicBidding.placementBidding")
+# columnsName_modify(df_campaign)
+
+def get_campaign_info_SB(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + token,
+              'Content-Type': 'application/vnd.sbcampaignresource.v4+json',
+              'Accept': """application/vnd.sbcampaignresource.v4+json"""}
+
+    url_ = "https://advertising-api.amazon.com/sb/v4/campaigns/list"
+
+    req_time = 0
+    while (req_time != 3):
+        req_time += 1
+        res = requests.post(url_, headers=header)
+        print(res.status_code)
+        if res.status_code not in [200, 207]:
+            time.sleep(3)
+        else:
+            return res.json()
+    return res.text
+
+# list_campaign_SB = get_campaign_info_SB(access_token)
+# df_campaign_SB = pd.json_normalize(list_campaign_SB['campaigns'])
+# df_campaign_SB = placement_segmentsplit(df_campaign_SB,"bidding.bidAdjustmentsByPlacement")
+# columnsName_modify(df_campaign_SB)
+
+def get_campaign_info_SD(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + token}
+
+    url_ = "https://advertising-api.amazon.com/sd/campaigns"
+
+    req_time = 0
+    while (req_time != 3):
+        req_time += 1
+        res = requests.get(url_, headers=header)  # V3版本为post请求
+        print(res.status_code)
+        if res.status_code not in [200, 207]:
+            time.sleep(3)
+        else:
+            return res.json()
+    return res.text
+# list_campaign_SD = get_campaign_info_SD(access_token)
+# df_campaign_SD = pd.json_normalize(list_campaign_SD)
+# df_campaign_SD['portfolioId'] = df_campaign_SD['portfolioId'].map(lambda x: int(x) if pd.isna(x)==False else -1)
+# columnsName_modify(df_campaign_SD)
+
+def get_adGroup_info_SP(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + access_token,
+              'Content-Type': "application/vnd.spAdGroup.v3+json",
+              'Accept': "application/vnd.spAdGroup.v3+json"
+              }
+
+    url_ = "https://advertising-api.amazon.com/sp/adGroups/list"
+    res = requests.post(url_, headers=header)
+    if res.status_code not in [200, 207]:
+        return res.text
+
+    token_ = res.json().get('nextToken')
+    temp_list = [res.json()['adGroups']]
+    while token_ != None:
+        res = requests.post(url_, headers=header, json={'nextToken': token_,"includeExtendedDataFields":True})
+        if res.status_code in [200, 207]:
+            res = res.json()
+            token_ = res.get('nextToken')
+            temp_list[0].extend(res['adGroups'])
+
+        else:
+            print(res.text)
+            break
+    return temp_list[0]
+# list_adGroup_SP = get_adGroup_info_SP(access_token)
+# df_adGroup_SP = pd.json_normalize(list_adGroup_SP)
+# columnsName_modify(df_adGroup_SP)
+
+def get_adGroup_info_SB(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + access_token,
+              'Content-Type': "application/vnd.sbadgroupresource.v4+json",
+              'Accept': "application/vnd.sbadgroupresource.v4+json"
+              }
+
+    url_ = "https://advertising-api.amazon.com/sb/v4/adGroups/list"  # V3版本
+    res = requests.post(url_, headers=header,json={"includeExtendedDataFields":True})  # V3版本为post请求
+    if res.status_code not in [200, 207]:
+        return res.text
+
+    token_ = res.json().get('nextToken')
+    temp_list = [res.json()['adGroups']]
+    while token_ != None:
+        res = requests.post(url_, headers=header, json={'nextToken': token_,"includeExtendedDataFields":True})
+        if res.status_code in [200, 207]:
+            res = res.json()
+            token_ = res.get('nextToken')
+            temp_list[0].extend(res['adGroups'])
+
+        else:
+            print(res.text)
+            break
+    return temp_list[0]
+
+
+# list_adGroup_SB = get_adGroup_info_SB(access_token)
+# df_adGroup_SB = pd.json_normalize(list_adGroup_SB)
+# df_adGroup_SB = time_stamp_convert(df_adGroup_SB,['extendedData.creationDate','extendedData.lastUpdateDate'])
+# columnsName_modify(df_adGroup_SB)
+
+def get_adGroup_info_SD(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + access_token
+              }
+
+    url_ = "https://advertising-api.amazon.com/sd/adGroups/extended"  # V3版本
+
+    res = requests.get(url_, headers=header)  # ,params={"startIndex":0,"count":1}
+    return res.json()
+
+# list_adGroup_SD = get_adGroup_info_SD(access_token)
+# df_adGroup_SD = pd.json_normalize(list_adGroup_SD)
+# df_adGroup_SD = time_stamp_convert(df_adGroup_SD,['creationDate','lastUpdatedDate'])
+# columnsName_modify(df_adGroup_SD)
+
+def get_adId_info_SP(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + access_token,
+              'Content-Type': "application/vnd.spProductAd.v3+json",
+              'Accept': "application/vnd.spProductAd.v3+json"
+              }
+    url_ = "https://advertising-api.amazon.com/sp/productAds/list"
+
+    res = requests.post(url_, headers=header, json={"includeExtendedDataFields": True})  # V3版本为post请求
+    if res.status_code not in [200, 207]:
+        return res.text
+    print(res.json())
+
+    token_ = res.json().get('nextToken')
+    temp_list = [res.json()['productAds']]
+    while token_ != None:
+        res = requests.post(url_, headers=header, json={'nextToken': token_, "includeExtendedDataFields": True})
+        if res.status_code in [200, 207]:
+            res = res.json()
+            print(res)
+            token_ = res.get('nextToken')
+            temp_list[0].extend(res['productAds'])
+
+        else:
+            print(res.text)
+            break
+    return temp_list[0]
+
+
+# list_adId_SP = get_adId_info_SP(access_token)
+# df_adId_SP = pd.json_normalize(list_adId_SP)
+# df_adId_SP = columnsName_modify(df_adId_SP)
+
+def get_adId_info_SB(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + access_token,
+              'Content-Type': "application/vnd.sbadresource.v4+json",
+              'Accept': "application/vnd.sbadresource.v4+json"
+              }
+    url_ = "https://advertising-api.amazon.com/sb/v4/ads/list"
+
+    res = requests.post(url_, headers=header)  # V3版本为post请求
+    if res.status_code not in [200, 207]:
+        return res.text
+#     print(res.json())
+    token_ = res.json().get('nextToken')
+    temp_list = [res.json()['ads']]
+    while token_ != None:
+        res = requests.post(url_, headers=header, json={'nextToken': token_})
+        if res.status_code in [200, 207]:
+            res = res.json()
+            print(res)
+            token_ = res.get('nextToken')
+            temp_list[0].extend(res['ads'])
+
+        else:
+            print(res.text)
+            break
+    return temp_list[0]
+
+def SB_segmentDeal(rel):
+    df = pd.json_normalize(rel)
+    df = time_stamp_convert(df,['extendedData.creationDate','extendedData.lastUpdateDate'])
+    df[["creative.asin1","creative.asin2","creative.asin3"]] = df['creative.asins'].map(str).str.slice(1,-1).str.replace("'","").str.split(",",expand=True).applymap(lambda x:None if x==None else x.strip())
+    df.drop(columns="creative.asins",inplace=True)
+    df = columnsName_modify(df)
+    return df
+#
+# list_adId_SB = get_adId_info_SB(access_token)
+# df_adId_SB = SB_segmentDeal(list_adId_SB)
+
+def get_adId_info_SD(token):
+    header = {'Amazon-Advertising-API-ClientId': "amzn1.application-oa2-client.ebd701cd07854fb38c37ee49ec4ba109",
+              'Amazon-Advertising-API-Scope': "3006125408623189",
+              'Authorization': 'Bearer ' + access_token
+              }
+    url_ = "https://advertising-api.amazon.com/sd/productAds/extended"
+
+    res = requests.get(url_, headers=header)
+    return res.json()
+
+
+# list_adId_SD = get_adId_info_SD(access_token)
+# df_adId_SD = pd.json_normalize(list_adId_SD)

+ 197 - 0
sync_amz_data/public/adstoken_OAUTH.py

@@ -0,0 +1,197 @@
+import json
+import requests
+import sys
+import time
+import os
+# from myapp.temp_get_budget_black_five.info import *
+
+#"C:\Users\ansjer\Documents\WXWork\1688858253398958\Cache\File\2023-08\autobid\autobid\info\token_info.json"
+class Ads_Api_Token(object):
+
+    def __init__(self, authorization_code='-1', profileId='-1', shop_name='-1') -> None:
+        sub_dir = os.path.abspath(os.path.dirname(__file__))
+        self.return_url = 'https://www.amazon.com/'
+        self.save_json_file_name = r"./token_info.json"# r"{sub_dir}\info\token_info.json".format(sub_dir=sub_dir)
+        self.lwa_info_file_name = r"./lwa_info.json"# r"{sub_dir}\info\lwa_info.json".format(sub_dir=sub_dir)
+        self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}
+        self.authorization_url = 'https://api.amazon.com/auth/o2/token'
+        self.authorization_code = authorization_code
+
+        # self.region = 'NA'
+        lwa_info = self._read_lwa_info()
+        self.lwa_client_id = lwa_info['lwa_client_id']
+        self.lwa_client_secret = lwa_info['lwa_client_secret']
+        self.access_token = self._get_access_token()
+
+        # 检查错误
+        if shop_name == '-1' or profileId == '-1':
+            print('错误:【shop_name或profileId没有初始化】')
+            print('作为广告商,你的客户列表:')
+            self._get_profile()
+            print('\n确认客户区域、名字等,选择name和profileId重新初始化shop_name和profileId')
+            sys.exit()
+        # print(self._get_profileId(name=shop_name),type(self._get_profileId(name=shop_name)))
+        if self._get_profileId(name=shop_name) != profileId:
+            print('错误:【检查profileId与shop_name不匹配】')
+            print('作为广告商,你的客户列表:')
+            self._get_profile()
+
+            print('\n确认客户区域、名字等,选择name和profileId重新初始化shop_name和profileId')
+            sys.exit()
+
+        self.shop_name = shop_name
+        self.profileId = profileId
+
+    def _read_lwa_info(self) -> str:
+        with open(self.lwa_info_file_name, 'r') as file_obj:
+            lwa_info = json.load(file_obj)
+        file_obj.close()
+        return lwa_info
+
+    def _read_token(self) -> str:
+        with open(self.save_json_file_name, 'r') as file_obj:
+            token = json.load(file_obj)
+        file_obj.close()
+        return token
+
+    def _write_token(self, token: dict) -> None:
+        """转换过期时间到秒级时间戳写入token
+
+        Args:
+            token (dict): token
+        """
+        token['expires_in'] += int(time.time())
+        with open(self.save_json_file_name, 'w') as file_obj:
+            json.dump(token, file_obj)
+
+    def _check_token_json(self, token: dict) -> bool:
+        """检查token合法性
+
+        Args:
+            token (dict): token
+
+        Returns:
+            bool: 是否合法
+        """
+        if 'access_token' in token and 'refresh_token' in token and 'expires_in' in token:
+            return True
+        else:
+            self._print_authorization_grant_info(error_type=1)
+
+    def _print_authorization_grant_info(self, error_type='-1'):
+        """打印授权的授权信息,获取授权code
+
+        Args:
+            error_type (str, optional): 0为找不到文件,1为文件内容不通过. Defaults to '-1'.
+        """
+        url = 'https://www.amazon.com/ap/oa?client_id=%s&scope=advertising::campaign_management&response_type=code&redirect_uri=%s' % (
+        self.lwa_client_id, self.return_url)
+        if error_type == 0:
+            print('==' * 10 + '未检测' + self.save_json_file_name + '==' * 10)
+        if error_type == 1:
+            print('==' * 10 + '内容不通过' + self.save_json_file_name + '==' * 10)
+        print('\t\t1.打开登陆地址' + url)
+        print('\t\t2.点击允许并登陆zhangside账号')
+        print('\t\t3.将重定向的url中的code保存下来')
+        print('\t\t4.将code填入初始化Token的authorization_code')
+        print('==' * 30)
+        sys.exit()
+
+    def _first_get_token(self, authorization_code: str) -> str:
+        """从授权的授权code申请token
+
+        Args:
+            authorization_code (str): 授权的授权code
+
+        Returns:
+            str: access_token
+        """
+        data = 'grant_type=authorization_code&code=%s&redirect_uri=%s&client_id=%s&client_secret=%s' % (
+        authorization_code, self.return_url, self.lwa_client_id, self.lwa_client_secret)
+        res = requests.post(self.authorization_url, data=data, headers=self.headers)
+        res = res.json()
+        self._check_token_json(res)
+        self._write_token(res)
+        return res['access_token']
+
+    def _refresh_token(self, limit_time_minute=3) -> str:
+        """刷新token,如果在授权时间还有多余limit_time_minute分钟不刷新直接返回access_token
+
+        Args:
+            limit_time_minute (int, optional): 剩余时间分钟. Defaults to 15.
+
+        Returns:
+            str: access_token
+        """
+        token = self._read_token()
+        self._check_token_json(token)
+        token_timestamp = token['expires_in']
+        if token_timestamp - int(time.time()) > limit_time_minute * 60:
+            return token['access_token']
+        data = 'grant_type=refresh_token&client_id=%s&refresh_token=%s&client_secret=%s' % (
+        self.lwa_client_id, token['refresh_token'], self.lwa_client_secret)
+        res = requests.post(self.authorization_url, data=data, headers=self.headers)
+        res = res.json()
+        self._check_token_json(res)
+        self._write_token(res)
+        return res['access_token']
+
+    def _get_access_token(self) -> str:
+        """根据状态获取token
+
+        Returns:
+            str: access_token
+        """
+        # 检查状态
+        if self.authorization_code == '-1':
+            if not os.path.exists(self.save_json_file_name):
+                self._print_authorization_grant_info(error_type=0)
+            token = self._read_token()
+            self._check_token_json(token)
+            access_token = self._refresh_token()
+            return access_token
+        else:
+            print('填入了code,获取授权的授权,下一次可不用填入code')
+            access_token = self._first_get_token(self.authorization_code)
+            return access_token
+
+    def _get_profileId(self, name):
+        profiles_url = 'https://advertising-api.amazon.com/v2/profiles'
+        data = {
+            'Amazon-Advertising-API-ClientId': self.lwa_client_id,
+            'Authorization': 'Bearer ' + self.access_token
+        }
+        res = requests.get(profiles_url, headers=data)
+        res = res.json()
+        profileId = '-1'
+        for customer_info in res:
+            if customer_info['accountInfo']['name'] == name:
+                profileId = customer_info['profileId']
+        return str(profileId)
+
+    def _get_profile(self):
+        profiles_url = 'https://advertising-api.amazon.com/v2/profiles'
+        data = {
+            'Amazon-Advertising-API-ClientId': self.lwa_client_id,
+            'Authorization': 'Bearer ' + self.access_token
+        }
+        res = requests.get(profiles_url, headers=data)
+        res = res.json()
+        print(res)
+
+
+if __name__ == "__main__":
+    # authorization_code = 'ANzRQnVlaRziQlNxrHGG'
+    access_token = Ads_Api_Token(shop_name = 'ZosiDirect',profileId='3006125408623189')
+    tken = access_token._get_access_token()
+    print(type(tken),tken)
+# {'profileId': 420999963953676,
+#  'countryCode': 'BR',
+#  'currencyCode': 'BRL',
+#  'dailyBudget': 999999999.0,
+#  'timezone': 'America/Sao_Paulo',
+#  'accountInfo': {'marketplaceStringId': 'A2Q3Y263D00KWC',
+#                  'id': 'A252W7I0ACJHS1',
+#                  'type': 'seller',
+#                  'name': 'ZosiDirect',
+#                  'validPaymentMethod': False}}