汇量科技JoyPac 实习

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_38688585/article/details/102721554

分析任务的流程

我们想爬去一个网站的内容,首先肯定需要登陆一个网址,这样才可以找到这个网站的内容,但我们不可能每次请求一个新的页面都需要重新登陆,这样太麻烦了,因而我们需要记录Http协议中的Session_id,只要记住了这个id,并添加到Headers 头,就可以不需要重复登陆了。
所以,做的第一件事就是如何找到这个session_id.
首先我们先查看登陆的过程,按下F12,查看network, 可以看到我们所需要的信息在 https://go.gameanalytics.com/api/v1/public/login/basic 中,如下图所示:

查看Response, 我们可以看到如下信息:

{"errors": [], "results": [{"linked": null, "token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJsaW5rZWQiOiBudWxsLCAiaWQiOiA0NTUyNiwgImV4cCI6IDE1NzE4OTk3MjcsICJyZW1lbWJlciI6IGZhbHNlfQ.HYfc6N03FrE_J1FX0YyemuxpMK4QPG1hAlBJBYQbwwM", "id": 45526, "exp": 1571899727, "remember": false}]}

其中的token 就是我们需要的, 可以进行验证,在网址中选择JoyPac的信息,再次查看可以看到如下信息:
JoyPac 所有游戏列表可以看到X-Authorization 正好等于之前的token,所以这个值显得十分重要。
接下来我们看看此次的Response,由于这个网站的设计问题,我们可以看到所有公司的游戏,因此如果我们需要自己的游戏,就需要查看他的json格式,从中找到我所需要的信息,通过json解析网址可以比较清楚的看到其结构化,截取其中一部分我所需要注意到信息如下:

 "studiosGames":[
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                Object{...},
                {
                    "createdTimestamp":1530773715,
                    "access":{
                        "role":"owner",
                        "level":99
                    },
                    "archived":false,
                    "imageFile":"1c277d29aa2718472b7bb07412c1725d.png",
                    "name":"JoyPac",
                    "disabled":false,
                    "games":[
                        {
                            "googleplay_key":null,
                            "access":{
                                "role":"owner",
                                "level":99
                            },
                            "game_key":"b260f4cea81a3abb956d397e78a5f49c",
                            "imageFile":"beff455e4ea3c72dd221758f6c8077cc.png",
                            "title":"Super Evasion 1",
                            "store_app":null,
                            "newEventStructureStatus":0,
                            "archived":false,
                            "is_beta_game":false,
                            "createdTimestamp":1530782719,
                            "onboarding":{
                                "update_game_1":true
                            },
                            "link_game_notification":false,
                            "dataApiToken":{
                                "token":"priv-eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJ0b2tlbiI6ICJleUpoYkdjaU9pQWlTRk15TlRZaUxDQWlkSGx3SWpvZ0lrcFhWQ0o5LmV5SmxlSEFpT2lBeE5UY3hPRGt5TkRBeGZRLjItUlp3eVI3SDVEVzMtaTlWUjVWNHRMQVBBb1U0ZElNaTRtQ0RkTGlRc28ifQ.LMciTHD3pBsOA4msC2rit5r0RYfM7qwBR79Ko_GaAeU",
                                "exp":1571892401
                            },
                            "store_platform":"apple_ios",
                            "disabled":false,
                            "bundle_id":"com.joypac.kaihi",
                            "amazon_key":null,
                            "featureFlags":null,
                            "id":54559,
                            "genres":[
                                70
                            ]
                        },

可以看到在studiosGames结构下找到了JoyPac,进一步结构下可以看到我们的所有游戏id,以及token,因此我们需要生成一个字典来记录对应的关系,方便后面的下载。
得到了所有游戏id以及对应的token后,我们就可以下载了,相同的操作可以看到下载的链接地址格式为:

https://query-0.gameanalytics.com/v1/games/id/export?start=1571616000&end=1571616000

其中id 为游戏的id start,end 为开始和截至的时间戳,要注意时区的问题。
好的,这样我们就得到了下载的链接,只需要下载解压即可。
整体流程就是这样,还是很清晰的。

获取token

由于是第一次做相关的任务,绕了不上弯子。
要访问网页,肯定需要用到post或者get ,先看下二者的区别:
(1) 在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。
(2) GET方式提交的数据最多只能有1024 Byte,而POST则没有此限制。
(3) 安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。
表单提交中get和post方式的区别归纳如下几点:
(1)get是从服务器上获取数据,post是向服务器传送数据。
(2)对于表单的提交方式,在服务器端只能用Request.QueryString来获取Get方式提交来的数据,用Post方式提交的数据只能用Request.Form来获取。
(3)一般来说,尽量避免使用Get方式提交表单,因为有可能会导致安全问题。比如说在登陆表单中用Get方式,用户输入的用户名和密码将在地址栏中暴露无遗。但是在分页程序中,用Get方式就比用Post好。
HTTP POST和GET的区别
1、HTTP 只有POST和GET 两种命令模式;
2、 POST 是被设计用来向上放东西的,而GET是被设计用来从服务器取东西的,GET也能够向服务器传送较少的数据,而Get之所以也能传送数据,只是用来设计告诉 服务器,你到底需要什么样的数据.POST的信息作为HTTP 请求的内容,而GET是在HTTP 头部传输的;
3、POST与GET在HTTP 中传送的方式不同,GET的参数是在HTTP 的头部传送的,而Post的数据则是在HTTP 请求的内容里传送;
4、POST传输数据时,不需要在URL中显示出来,而GET方法要在URL中显示;
5、 GET方法由于受到URL长度的限制,只能传递大约1024字节;POST传输的数据量大,可以达到2M,而根据微软方面的说法,微软对用 Request.Form() 可接收的最大数据有限制,IIS 4 中为 80 KB 字节,IIS 5 中为 100 KB 字节;
6、SOAP是依赖于HTTP POST模式实现的;
原文链接

其次,我看到了一个写的不错的request.get,post 的使用,先mark 一波
request.post 和 request.get使用

接下来是实际的操作了,弄懂了上面的东西,其实就很简单了,我们只需要向url post 一个请求,带上账户信息,结果看到我们所需要的response了。
具体代码如下:

def gettoken(url,headers):
    request_param={
    "email": '******',
    "password": '******',
    "remember": False
    }
    response=requests.post(url,data=json.dumps(request_param), headers=headers)
    get = response.json()["results"][0]
    print(get["token"])
    print(type(get["token"]))
    return get["token"]

在request_param 中带上所需要的信息就可以,这里我的url 是:
“https://go.gameanalytics.com/api/v1/public/login/basic”
具体依据情况改变就可 。
这样我们就获得了所需要的token,感觉也很简单哈哈哈。
在代码中 .json()函数可以将json 格式转换为字典格式,方便我们进行操作,向get[“token”] 就可以直接获得其中的token 值,字典有点类似与java的哈希表? 但是感觉用起来更方便。

获取游戏id

获取游戏id 感觉和token是一模一样的,因为我们已经获取token 了,所以只需要在headers中加入这个值就可以了,主要操作就是将json 转换为字典格式后,获取我们所需要的值,直接贴代码吧!

扫描二维码关注公众号,回复: 7578580 查看本文章
def getmygame(token):
    headers = {
        "X-Authorization": token
    }
    res_game = requests.get('https://go.gameanalytics.com/api/v1/user/data', headers=headers)
    # 调用get方法,下载这个字典
    json_game = res_game.json()
    # 使用json()方法,将response对象,转为列表/字典
    print(type(json_game))
    print(json_game)
    return json_game
def get_mygame_id(StudioGame_list):
    game_id_dict = {}
    for i in range(len(StudioGame_list)):
        dict_game = StudioGame_list[i]
        if dict_game["name"] == "JoyPac":
            print(StudioGame_list[i]["name"])
            print("games 类型")
            print(type(dict_game["games"]))
            for j in range(len(dict_game["games"])):
                game_id_dict[dict_game["games"][j]["id"]] = dict_game["games"][j]["dataApiToken"]["token"]
    print(game_id_dict)
    return game_id_dict

这里涉及到了字典和List 的遍历,由于是第一次使用,也做一个记录吧!

List 遍历

# 方法1
print '遍历列表方法1:'
for i in list:
    print("序号:%s   值:%s" % (list.index(i) + 1, i))

# 方法2
print '\n遍历列表方法2:'
for i in range(len(list)):
    print("序号:%s   值:%s" % (i + 1, list[i]))

# 方法3
print '\n遍历列表方法3:'
for i, val in enumerate(list):
    print("序号:%s   值:%s" % (i + 1, val))

字典遍历

(1) 遍历Key值

>>> a
{'a': '1', 'b': '2', 'c': '3'}
>>> for key in a:
       print(key+':'+a[key])
 
a:1
b:2
c:3
>>> for key in a.keys():
       print(key+':'+a[key])
 
a:1
b:2
c:3

(2)遍历value值

>>> for value in a.values():
       print(value)
 
1
2
3

(3)遍历字典项

>>> for kv in a.items():
       print(kv)
 
('a', '1')
('b', '2')
('c', '3')

(4)遍历字典键值

for key,value in a.items():
print(key+’:’+value)

a:1
b:2
c:3

for (key,value) in a.items():
print(key+’:’+value)

a:1
b:2
c:3

获取数据下载链接

创建一个字典进行存储,每个Id 对应自己的链接,每个链接有List存储,整体操作类似,代码如下:

def get_download_linkdict(game_id_dict,timestamp,token):
    yesterday_timestamp = timestamp
    link_dict = {}
    for key in game_id_dict:
        headers = {
            "Authorization": game_id_dict[key]
        }
     # 拼接url 获取每个游戏的下载链接
        url = "https://query-0.gameanalytics.com/v1/games/"+str(key)+"/export?start="+str(yesterday_timestamp)+"&end=" + str(yesterday_timestamp)
        link_game = requests.get(url, headers=headers)
        download_link = link_game.json()
        print(download_link)
        demo = []
        #每个游戏的链接由一个list 存储 再有一个dict 存储每个游戏的list

        for i in range(len(download_link)):
            demo.append(download_link[i]["url"])
    #print(demo)
        link_dict[key] = demo
    print(link_dict)
    return link_dict

下载

下载的时候先利用 os.path.join()生成一个目录,并别需要判断目录是否存在,否则可能会报错。遍历字典,获取每个Id的链接进行下载。
下载主要用到的函数为:
urllib.request.urlretrieve(link_dir[key][i], downpath)
这个函数功能为:

urlretrieve(url, filename=None, reporthook=None, data=None)
参数 finename 指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。)
参数 reporthook 是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。
参数 data 指 post 到服务器的数据,该方法返回一个包含两个元素的(filename, headers)元组,filename 表示保存到本地的路径,header 表示服务器的响应头。
def download_data_gz(link_dir, timestamp):
    dir = os.path.join('C:\data', str(timestamp))
    isExists = os.path.exists(dir)
    if not isExists:
        # 如果不存在则创建目录
        # 创建目录操作函数
        os.makedirs(dir)
    else:
        # 如果目录存在则不创建,并提示目录已存在
        print(' 目录已存在')
    for key in link_dir:
        data_dir = os.path.join(dir, str(key))
        isExists = os.path.exists(data_dir)
        if not isExists:
            # 如果不存在则创建目录
            # 创建目录操作函数
            os.makedirs(data_dir)
        else:
            # 如果目录存在则不创建,并提示目录已存在
            print(' 目录已存在')

        for i in range(len(link_dir[key])):
            name = link_dir[key][i].split('?')[-2].split('/')[-1]
            downpath = os.path.join(data_dir, name)
            urllib.request.urlretrieve(link_dir[key][i], downpath)
        print(data_dir)
        un_gz_Tree(data_dir)
        delete_gz_tree(data_dir)

解压缩,删除文件

def un_gz(file_name):
    """解压单个文件"""
    f_name = file_name.replace(".gz", "")
    # 获取文件的名称,去掉
    g_file = gzip.GzipFile(file_name)
    # 创建gzip对象
    open(f_name, "wb+").write(g_file.read())
    # gzip对象用read()打开后,写入open()建立的文件里。
    g_file.close()
    print("解压完毕",end=' ')
    print(file_name)


def un_gz_Tree(path):
    # 解压文件夹中的zip文件
    print(path)
    if not os.path.exists(path):               # 如果本地文件夹不存在,则创建它
        print("不存在文件夹")
        os.makedirs(path)
    for file in os.listdir(path):               #listdir()返回当前目录下清单列表
        Local = os.path.join(path, file)        #os.path.join()用于拼接文件路径
        print("开始解压")
        print(Local)
        if os.path.splitext(Local)[1] == '.gz':            #os.path.splitext(Remote)[1]获取文件扩展名,判断是否为.zip文件
             un_gz(Local)       #解压文件
def delete_gz_tree(path):
    print("开始删除")
    print(path)
    if not os.path.exists(path):  # 如果本地文件夹不存在,则创建它
        print("不存在文件夹")
    for file in os.listdir(path):  # listdir()返回当前目录下清单列表
        Local = os.path.join(path, file)  # os.path.join()用于拼接文件路径
        print("删除压缩包",end=' ')
        print(Local)
        if os.path.splitext(Local)[1] == '.gz':  # os.path.splitext(Remote)[1]获取文件扩展名,判断是否为.gz文件
            delete_gz(Local)  # 解压文件
def delete_gz(file_name):
    if (os.path.exists(file_name)):
        os.remove(file_name)
    else:
       print("要删除的文件不存在!")

猜你喜欢

转载自blog.csdn.net/qq_38688585/article/details/102721554