视频网站的接口解析

您所在的位置:网站首页 影视会员接口怎么用 视频网站的接口解析

视频网站的接口解析

2024-07-03 22:30| 来源: 网络整理| 查看: 265

先把代码放上来

import base64 import hashlib import json import re import time import requests import urllib3 urllib3.disable_warnings() def get_data(url, utid): """ 生成data参数 :param url: 视频地址 :return: """ # 从连接中获取vid vid = url.split('id_')[-1].split('.')[0] # 获取部分url用于生成加密参数 url_ = url.split('//')[-1].split('?')[0] # base64 加密 emb = base64.b64encode(("809715843" + url_).encode('utf-8')).decode('utf-8') data = {"biz_params": {"vid": vid}, "ad_params": { "atm": "", "aw": "w", "bt": "pc", "d": "0", "dq": "auto", "emb": emb, "fu": "0", "isvert": "0", "needbf": "2", "os": "win", "osv": "10", "p": "1", "partnerid": "null", "pver": "0.6.16", "rst": "mp4", "site": "1", "sver": "1.1", "vip": "0", "vs": "1", "wintype": "interior" }, "steal_params": { "ccode": "0502", "client_ip": "192.168.1.1", "client_ts": str(round(time.time() * 1000)), "utid": utid, "version": "0.6.16", "ckey": "DIl58SLFxFNndSV1GFNnMQVYkx1PP5tKe1siZu/86PR1u/Wh1Ptd+WOZsHHWxysSfAOhNJpdVWsdVJNsfJ8Sxd8WKVvNfAS8aS8fAOzYARzPyPc3JvtnPHjTdKfESTdnuTW6ZPvk2pNDh4uFzotgdMEFkzQ5wZVXl2Pf1/Y6hLK0OnCNxBj3+nb0v72gZ6b0td+WOZsHHWxysSo/0y9D2K42SaB8Y/+aD2K42SaB8Y/+ahU+WOZsHcrxysooUeND" } } data_ = dict() # 将参数json化 for key, value in data.items(): data_[key] = json.dumps(value) return json.dumps(data_) def get_all_parameter(data_, token=''): """ 获得所有参数 :param data_: data参数 :param token: token参数 :return: """ t = str(round(time.time() * 1000)) data = { 'jsv': '2.5.0', 'appKey': '24679788', 't': t, 'api': 'mtop.youku.play.ups.appinfo.get', 'v': '1.1', 'sign': get_sign(t, data_, token), 'timeout': '20000', 'YKPid': '20160317PLF000211', 'YKLoginRequest': 'true', 'AntiFlood': 'true', 'AntiCreep': 'true', 'type': 'jsonp', 'dataType': 'jsonp', 'callback': 'mtopjsonp1', 'data': data_ } return data def get_sign(t, data, token): """ :param t: 13位时间戳 :param data: 请求时的参数data :param token: 从cookie中获得 :return: 加密后的sign """ appKey = '24679788' sign = token + '&' + t + '&' + appKey + '&' + data md5 = hashlib.md5() md5.update(sign.encode('UTF-8')) sign = md5.hexdigest() return sign def get_interface(url, utid, session, headers, proxies=None): # 支持代理和无代理两种请求 """ 获取视频借口内容 :param url: 视频连接 :return: """ data_ = get_data(url, utid) data = get_all_parameter(data_) url = 'https://acs.youku.com/h5/mtop.youku.play.ups.appinfo.get/1.1/' if not proxies: response = session.get(url, params=data, verify=False, headers=headers) else: response = session.get(url, params=data, verify=False, headers=headers, proxies=proxies) # print(response.text) if '令牌为空' in response.text: # 从cookie中获取token token = response.cookies['_m_h5_tk'].split('_')[0] print("获取token", token) data = get_all_parameter(data_, token=token) data['callback'] = 'mtopjsonp1' # 请求接口 if not proxies: response = session.get(url, params=data, verify=False, headers=headers) else: response = session.get(url, params=data, verify=False, headers=headers, proxies=proxies) return response.text def parse(url, utid): result = '' times = 1 headers = { 'Host': "acs.youku.com", 'Connection': "keep-alive", 'Pragma': "no-cache", 'Cache-Control': "no-cache", 'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/72.0.3626.119 Safari/537.36", 'Accept': "*/*", 'Referer': url, 'Accept-Encoding': "gzip, deflate, br", 'Accept-Language': "zh-CN,zh;q=0.9", 'cache-control': "no-cache", } while times: session = requests.Session() proxies = {} time.sleep(5) try: result = get_interface(url, utid, session, headers) except: result = '' if len(result) > 10000: break else: times -= 1 print(result) def get_utid(): t = int(time.time() * 1000) url = 'https://log.mmstat.com/eg.js?t={}'.format(t) headers = { 'authority': 'log.mmstat.com', 'method': 'GET', 'path': '/eg.js', 'scheme': 'https', 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9', 'referer': 'https://v.youku.com/', 'sec-fetch-dest': 'script', 'sec-fetch-mode': 'no-cors', 'sec-fetch-site': 'cross-site', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36' } resp = requests.get(url, headers=headers) print(resp.text) utid = re.search('Etag="(.*?)"', resp.text, re.S).group(1).strip() return utid if __name__ == '__main__': utid = get_utid() print('访问链接获取', utid) parse('https://v.youku.com/v_show/id_XNDA4NTM4NTQwMA==.html', utid) print('使用selenium获取') utid = 'dAPfGLzvZ2ICAbcOhzje/chE' parse('https://v.youku.com/v_show/id_XNDA4NTM4NTQwMA==.html', utid)

一些参数的加解密就不多做介绍了,在一些博主的文章里有很详细的逆向思路和解析。

这里主要说一下,如果有大量的类似访问,导致接口返回异常的分析。

在程序入口,parse方法传入两个参数,一个是url,没啥好说的,另一个就是要分析的主角之一:utid。

utid相当于该网站给每个用户生成的唯一id,那它是如何生成的呢?

我们先打开一个无缓存的浏览器。

要先打开下方的抓包界面

输入URL回车,看看发起了哪些请求:

如上图,有个https://log.mmstat.com/eg.js,右侧被标记的,就是代码里的utid。

为什么要把这个utid单独拿出来说呢。

优酷对于该接口的访问有两个判断

1,某个ip高频次的访问,该接口会报异常,返回无用的数据

2,某个utid高频次的访问,该接口会报异常,返回用户账号异常

那么针对第一种情况,我们可以使用代理绕过。

第二种情况,就需要更换utid了。

上面介绍说,使用https://log.mmstat.com/eg.js去获取utid,可行吗?

经过试验,是不可行的,对https://log.mmstat.com/eg.js进行请求,无论如何构造请求头,或者使用代理获取utid,都能正常获取到utid。

但是,获取到的utid确是不可用的,使用上述方法获取到的utid去访问接口,依旧无法获取到数据。

那,如果真的对该目标接口需要大量的访问,而没有utid,该怎么办呢。

简单,上面也说了,使用无缓存的浏览器打开页面就会产生一个utid,这个utid是可用的。那我们只需要一直打开无缓存的浏览器,获取utid,把utid保存下来,当我们有足够的utid,理论上就可以达到我们的目的。

可是,当某个ip高频次的打开浏览器访问链接,那么浏览器页面也会弹出警告,提示登录。

于是,我们想到了代理。

思路就有了,使用隧道代理+selenium+chromedriver,执行打开模拟器访问该网站页面,utid就在cookie里,获取cookie里的utis存库,在使用的时候随机取,就可以达到我们的目的。

seleniu+隧道代理+chromedriver的使用方法:https://blog.csdn.net/s_kangkang_A/article/details/115323462 在代码中我写了一个对比,获取到的数据如下:

很明显验证了上面的所述。

还有一个主角,session

在代码中,请求用到了session,这是必不可少的,因为保持状态的访问才能获取到重要参数,token

 

 

 

重要更新

从 https://log.mmstat.com/eg.js 获取的utid真的不可用吗?为什么?怎么使之变得可用?

请看分析:https://blog.csdn.net/s_kangkang_A/article/details/116754192



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3