123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143 |
- import requests
- import uuid
- import random
- import time
- import json
- import hashlib
- from libs.aesgzip import tt_encrypt
- from urllib import parse
- from libs.proxy import Proxy
- from rds_model.db_redis import DbRedis
- def get_mc():
- def a():
- seed = "1234567890ABCDEF"
- sa = []
- for i in range(2):
- sa.append(random.choice(seed))
- salt = ''.join(sa)
- return salt
- k = ''
- for i in range(6):
- k += a() + ':'
- return k[:-1]
- def get_random(i, random_type=1):
- if random_type == 1:
- return str(random.randint(1 * 10 ** (i - 1), 1 * 10 ** i - 1))
- elif random_type == 8:
- seed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- sa = []
- for i in range(i):
- sa.append(random.choice(seed))
- salt = ''.join(sa)
- return salt
- else:
- seed = "1234567890abcde"
- sa = []
- for i in range(i):
- sa.append(random.choice(seed))
- salt = ''.join(sa)
- return salt
- def get_random_brand_type():
- brand_type = get_random(3, random_type=8) + '-' + get_random(2, random_type=8) + '00'
- return brand_type
- V1 = str(random.randint(5,8))
- V2 = str(random.randint(0,9))
- channel = 'oppo'
- device_type_list = ['VTR-AL00', 'KNT-AL10', 'PRA-AL00', 'DUA-TL00', 'PLK-AL10', 'KIW-AL10', 'LON-AL00', 'ANA-AN00',
- 'JSC-AN00', 'TAS-AN00', 'TAS-AL00']
- # device_type = 'GRL-CL00'
- device_type = get_random_brand_type()
- device_brand = 'HUAWEI'
- # Y79, Y66i, V7, X20, X20Plus, V7+, X9s L,V5s,Y66,Y30
- # device_type = random.choice(device_type_list)
- # channel_list = ['huawei', 'googleplay', 'douyin-huidu-guanwang-test', 'douyin_tengxun_wzl',
- # 'wandoujia_zhiwei', 'update']
- # channel = random.choice(channel_list)
- # print(channel, device_type)
- cookie = ''
- class DouYinApi:
- #USER_AGENT = 'okhttp/3.10.0.1'
- USER_AGENT = f'com.ss.android.ugc.aweme/{V1}{V2}0 (Linux; U; Android 5.1.1; zh_CN; {device_type}; Build/LMY47V; Cronet/58.0.2991.0)'
- COMMON_DEVICE_PARAMS = {
- 'retry_type': 'no_retry',
- 'ac': '4g',
- 'channel': channel,
- 'aid': '2329',
- 'app_name': 'aweme',
- 'version_code': f'{V1}{V2}0',
- 'version_name': f'{V1}.{V2}.0',
- 'device_platform': 'android',
- 'ssmix': 'a',
- 'device_type': device_type,
- 'device_brand': device_brand,
- 'language': 'zh',
- 'os_api': '25',
- 'os_version': '7.1.2',
- 'manifest_version_code': f'{V1}{V2}0',
- 'resolution': '720*1280',
- 'dpi': '192',
- 'update_version_code': f'{V1}{V2}02',
- 'mcc_mnc': '46000'
- }
- PROXY = {}
- def __init__(self, sessionid, proxies):
- """
- :param cid: client id
- """
- self.proxies = proxies
- self.__cid = ''
- self.__device_id = ''
- self.__iid = ''
- self.__uuid = ''
- self.__openudid = ''
- self.__device_params = {}
- self.__cookie = {
- }
- def init_device_ids(self, device_id, iid, udid, openudid, cc=None):
- """初始化设备id参数
- :param device_id: device id
- :param iid: install id
- :param udid: imei
- :param openudid: open udid
- :param serial_number: serial no
- :param clientudid: client udid
- :param sim_serial_number: sim serial number
- :param mc: mac address
- :return: none
- """
- self.__device_id = device_id
- self.__iid = iid
- self.__uuid = udid
- self.__openudid = openudid
- device_ids = {
- 'uuid': udid,
- 'openudid': openudid
- }
- if device_id and iid:
- device_ids.update({
- 'device_id': device_id,
- 'iid': iid,
- })
- self.__device_params = self.COMMON_DEVICE_PARAMS.copy()
- self.__device_params.update(device_ids)
- if cc:
- self.__cookie.update(cc)
- def __get_encrypted_device_info(self, device_id, openudid, udid, clientudid, serial_number, mac, iid):
- register_info = {
- "magic_tag": "ss_app_log",
- "header": {
- "display_name": "抖音短视频",
- "update_version_code": int(self.COMMON_DEVICE_PARAMS['update_version_code']),
- "manifest_version_code": int(self.COMMON_DEVICE_PARAMS['manifest_version_code']),
- "aid": '2329',
- "channel": self.COMMON_DEVICE_PARAMS['channel'],
- "appkey": "57bfa27c67e58e7d920028d3",
- "package": "com.ss.android.ugc.aweme",
- "app_version": self.COMMON_DEVICE_PARAMS['version_name'],
- "version_code": int(self.COMMON_DEVICE_PARAMS['version_code']),
- "sdk_version": "2.5.5.8",
- "os": "Android",
- "os_version": self.COMMON_DEVICE_PARAMS['os_version'],
- "os_api": self.COMMON_DEVICE_PARAMS['os_api'],
- "device_model": self.COMMON_DEVICE_PARAMS['device_type'],
- "device_brand": self.COMMON_DEVICE_PARAMS['device_brand'],
- "device_manufacturer": self.COMMON_DEVICE_PARAMS['device_brand'],
- "cpu_abi": "armeabi-v7a",
- "build_serial": serial_number,
- "release_build": "fbfabbc_20190522",
- "density_dpi": self.COMMON_DEVICE_PARAMS['dpi'],
- "display_density": "mdpi",
- "resolution": "1280x720",
- "language": "zh",
- "mc": mac,
- "timezone": 8,
- "access": "4G",
- "not_request_sender": 0,
- "rom": "EMUI-rel.se.infra.20191210.155925",
- "rom_version": "HUAWEI-user 7.1.2 20171130.276299 release-keys",
- "sig_hash": "aea615ab910015038f73c47e45d21466",
- # "device_id": str(device_id),
- "openudid": str(openudid),
- "udid": str(udid),
- "clientudid": str(clientudid),
- "serial_number": str(serial_number),
- "sim_serial_number": [
- ],
- "region": "CN",
- "tz_name": "Asia/Shanghai",
- "tz_offset": 28800
- },
- "_gen_time": str(round(time.time() * 1000))
- }
- if device_id:
- register_info['header']['device_id'] = str(device_id)
- if iid:
- register_info['header']['iid'] = str(iid)
- register_info['header']['push_sdk'] = '[1, 2, 6, 7, 8, 9]'
- return tt_encrypt((json.dumps(register_info)))
- def log_settings(self, ids):
- device_id = ids['device_id']
- openudid = ids['openudid']
- udid = ids['uuid']
- clientudid = ids['clientudid']
- serial_number = ids['serial_number']
- iid = ids['iid']
- mc = ids['mc']
- d = self.__get_encrypted_device_info(device_id, openudid, udid, clientudid, serial_number, mc, iid)
- url = 'https://log.snssdk.com/service/2/log_settings/?'
- url = self.__add_other_params(url, {})
- sign = self.__get_sign(url)
- if self.proxies:
- resp = requests.post(url, headers=self.__get_headers(sign), cookies=self.__cookie, proxies=self.proxies,
- data=d, verify=False, timeout=20)
- else:
- resp = requests.get(url, headers=self.__get_headers(sign), cookies=self.__cookie, data=d, verify=False, timeout=20)
- # print(resp.text)
- def xlog(self, device_id, iid, udid, openudid, serial_number):
- xlog = {
- "dpod": {
- "pod": ""
- },
- "p1": f"{device_id}",
- "p2": f"{iid}",
- "ut": 72,
- "ait": int(time.time() - 72),
- "pkg": "com.ss.android.ugc.aweme",
- "fp": "HUAWEI/HUAWEI/VOG-AL00:5.1.1/20171130.376229:user/release-keys",
- "vc": 0,
- "vpn": 0,
- "wifisid": "",
- "wifimac": "",
- "wifip": "",
- "aplist": [
- ],
- "route": {
- "iip": "0",
- "gip": "0",
- "ghw": "0",
- "type": "0"
- },
- "location": "",
- "apps": ["com.microvirt.guide", "com.android.browser", "com.ss.android.ugc.aweme"],
- "mdi_if": {
- },
- "extra": "install",
- "hw": {
- "brand": self.COMMON_DEVICE_PARAMS['device_brand'],
- "model": self.COMMON_DEVICE_PARAMS['device_type'],
- "board": self.COMMON_DEVICE_PARAMS['device_brand'],
- "device": self.COMMON_DEVICE_PARAMS['device_type'],
- "product": self.COMMON_DEVICE_PARAMS['device_type'],
- "display": "720*1280",
- "dpi": 0,
- "bat": 1000,
- "cpu": {
- "core": 2,
- "hw": "placeholder",
- "max": "2400000",
- "min": "1000000",
- "ft": "neon vfp swp half thumb fastmult edsp vfpv3"
- },
- "mem": {
- "ram": "2120286208",
- "rom": "8320901120"
- }
- },
- "id": {
- "i": 22,
- "r": "5.1.1",
- "imei": f"{udid}",
- "imsi": '46000' + str(self.__get_random(10)),
- "adid": f"{openudid}",
- "adid_ex": f"{openudid}",
- "mac": '',
- "serial": serial_number
- },
- "emulator": {
- },
- "env": {
- "ver": "0.6.02.17",
- "tag": "default",
- "pkg": "com.ss.android.ugc.aweme",
- "tz": "GMT+08:00",
- "ml": "zh_CN",
- "uid": 10045,
- "rebuild": 0,
- "jd": 0,
- "dbg": -1,
- "tid": 0,
- "xposed": 0,
- "hk": [
- "__system_property_get",
- "fopen",
- "fgets",
- "fread",
- "getpid",
- "gettid",
- "dlopen",
- "dlsym",
- "dladdr"],
- "su": 0,
- "sp": "/system/xbin/su",
- "ro.secure_s": "1",
- "ro.debuggable_s": "0",
- "click": "",
- "hph": "",
- "hpp": "",
- "mc": 0,
- "fc": 946933748,
- "jexp": 0,
- "frida": 0,
- "cydia": 0,
- "vapp": ""
- },
- "extension": {
- "bt": -1,
- "notify": 2212858197,
- "sign": "AEA615AB910015038F73C47E45D21466",
- "bytes64": "Aa1IrwSQLRXfmUvJokUpTkHJ9Yh1G4lpVgZSOaZeri+QVgSy80D5ID5UbH6x6xcSHsdjXqljImqg/LxoSbAeyqYZ67ZUTE23KmeyzHjTOeTtGogSEQY2/D8UWmY7Xt815Ch96RiLEgmzqnzCGZ0/N2AAaS5FynrMMfNv9jPlZgcZBjlWv5Ept44wrLJ+G1rJ7CzjL567O2ClTXKGTbHDTZsh91lWXmcNKzsh9PReifo2kf9f2MvJnJ9mN80soe7hw+/96olR5tTH6yVpsbuJt0NjxXI+y5yKp+GLueKCeYbG4QIqqI4buMEsjnPQCOm1bZtYxqeevC1aJVlNMdoQSZjZ7xqsWk8cNBuXqe/XXQua4QIqqI4buMEsjnPQCOm1bWat8qmH4OhJGLtb/aaNzHlXbo7P3DIJUsaOqMvCZvAN5apd9qaCQuvbISV7KJveRYfCRQGc0wiPPEaBEF7iO6qDRjlTDdNocBDAc6VdJS27EXEPHFPIH40PlLnx7vTDN6kUtGcG6G07pnlwwdAp6VZJskS5EmTY0MWyrPBOzBug+bRJCza4pcoC5A8ALNOUc39lxIAX7NuMJcf5rmTmkg8asiKpeeQHm2lSK5YNJkldp4+JLVggF/F+Dr6JjhyhERFxDxxTyB+ND5S58e70wzcNUOIjqUHt95eTwSOIFJvTZ+ZxXM4kDOGCeZXOBoqAfUbYgYfGrRZtcMdw1Lra0HN713ei+bcfoILrHoJO4fS3ZEq1jSU2d8XDEIid38oMwYrPyzXQOAQ/eRZlCiMSW83LMCj/4N0KpL/qlOzmB0uiBqKuF73Qhd0IfQTPpVCrwO6P/upwe1Q8yj+kXQBntfARcQ8cU8gfjQ+UufHu9MM3QpsZRTCVwNPhHp7m8lPb3/6YAZdknQzHMOVZp/LM1kf9MvhPN3heC2rp/QwWY1p+IPPe4wuRVVSO2vyJ8PhyDQxltLZjJW23706uyu+wGLFBiE7+4WBKMHWO3JmR6TWuHglclf+zh1CT21Wy5n/3Ex732O0WkYD01c/U27BcQ2Gb5RZdXYfhXTJe6VIzQnf02PCccLK2HnTdZ6tZ4qquKhkB0gKbMhtx/V5sBYe38cgU+5ct4Zy3fRwT/i5HkB2Wh6UlY2Ty1vIfaakVcR9dC7TKHDAWLIO0CPgBDeZFdb1zfIGyz50R3D9FNBoXkK6o5MRSDrM+pK5mlxZPJ0n56WiqDTEjAaxwEDWLejQFgyczb8DTeJnn5+nvyP/5jmfdv9sb7e8tpPlu02HsOtNzRLZRdpI3mgFYLPF0AJz2DHf90TVVUkETnF3ts+CqH34sIKT0zmoYjvpKGzdznMgRkJMPB3/Q4n/SZqJYVx9Bae0yYyFhtXt6XCdLgBPreyCy57dyB/svbMR4tvQ6K6W28yo9zGrt6gp20h6UzBfquQkOfB1SPLAqdyCyEcbja+ew+LgOejtotPR6lPJ7gUDbIoBURxkdLpINVc0RirdDBYeDaH3sZPli2YneQthTQCW91O6bRzlAEbljd7NTi3OomYuf+aUu8Y5rTjnyJAig+jSORIsyBHYeyrnBuAbFZUsvC5yRvAfEf6Uf1KWgGjcplhfxnBb4ocrYARhO5NCkCRg66GqLCXUDUpm2Gh2mN17vPXAF2ZH+W/hUtmsTs5zkJwks+vnWRDGs9QZWzkUUd2A/eHRxxHqx51yqZKT6v6uuF716rYsthonl01CqAJe7q0jq//hm7ZwCwWyY+GxkxON9PRgo36h0MOgFSURMf/C8pOUz21p3kXrPxmoPxXrisOD5U3oCiOe01fWZoxtAHCzgQpWtnDwqPVxohTwXyShv",
- },
- "rl": {
- },
- "ssp": {
- },
- "grilock": "eyJvcyI6IkFuZHJvaWQiLCJ2ZXJzaW9uIjoiMS4wLjAiLCJ0b2tlbl9pZCI6IiIsImNvZGUiOjUwNH0="
- }
- s = (json.dumps(xlog))
- url = f"https://xlog.snssdk.com/v2/r?os=0&ver=0.6.02.17&m=1&app_ver=5.5.0®ion=CN&aid=2329&did={device_id}"
- data = {"post_d": s, "url": url}
- r = requests.post("http://192.168.77.186:18400/xlogr", data=str(data), timeout=20).text
- # print(r)
- def register_device(self):
- udid = '8678' + get_random(11)
- serial_number = "71623411"
- openudid = 'c2a5' + str(uuid.uuid4())[-12:]
- clientudid = str(uuid.uuid4())
- mc = get_mc()
- """获取设备信息,传参数注册老设备,不传参数注册新设备
- :return:
- """
- # serial_number = str(uuid.uuid4())[-12:]
- # if openudid is None:
- # openudid = 'fa23' + str(uuid.uuid4())[-12:]
- # clientudid = str(uuid.uuid4())
- # if udid is None:
- # udid = '861' + self.__get_random(12)
- # mc = self.__get_random_mac()
- # if device_id is None:
- # device_id = '825739' + self.__get_random(9)
- params = {
- 'uuid': udid,
- 'openudid': openudid,
- '_rticket': str(int(round(time.time() * 1000)))
- }
- params.update(self.COMMON_DEVICE_PARAMS)
- device_register_url = 'https://log.snssdk.com/service/2/device_register/?' + parse.urlencode(params)
- headers = {
- 'User-Agent': DouYinApi.USER_AGENT
- }
- d = self.__get_encrypted_device_info(None, openudid, udid, clientudid, serial_number, mc, iid=None)
- if self.proxies:
- resp = requests.post(device_register_url,
- data=d, proxies=self.proxies,
- headers=headers, verify=False, timeout=20)
- else:
- resp = requests.post(device_register_url,
- data=d,
- headers=headers, verify=False, timeout=20)
- cookie = resp.cookies.get_dict()
- if len(cookie) != 0:
- self.__cookie.update(cookie)
- # print(self.__cookie)
- resp = resp.json()
- ids = {
- 'new_user': resp['new_user'],
- 'device_id': str(resp['device_id']),
- 'iid': str(resp['install_id']),
- 'uuid': udid,
- 'openudid': openudid,
- 'serial_number': serial_number,
- 'clientudid': clientudid,
- 'mc': mc,
- 'cookie': parse.urlencode(self.__cookie)
- }
- return ids
- def app_log(self):
- params = {
- 'uuid': udid,
- 'openudid': openudid,
- '_rticket': str(int(round(time.time() * 1000)))
- }
- params.update(self.COMMON_DEVICE_PARAMS)
- device_register_url = 'https://log.snssdk.com/service/2/app_log/?' + parse.urlencode(params)
- headers = {
- 'User-Agent': DouYinApi.USER_AGENT
- }
- data = {"device_info": device_info, 'url': device_register_url, 'ck': ''}
- gorgon = requests.post("http://192.168.77.186:18400/app_log", data=str(data), timeout=20).json()
- d = tt_encrypt(device_info)
- if self.proxies:
- resp = requests.post(device_register_url,
- data=d, proxies=self.proxies,
- headers=headers, verify=False, timeout=20)
- else:
- resp = requests.post(device_register_url,
- data=d,
- headers=headers, verify=False, timeout=20)
- cookie = resp.cookies.get_dict()
- if len(cookie) != 0:
- self.__cookie.update(cookie)
- resp = resp.json()
- # print(resp)
- return
- def get_feed(self):
- """获取首页推荐列表
- """
- douyin_url = 'https://aweme-eagle.snssdk.com/aweme/v1/feed/?type=0&max_cursor=0&min_cursor=-1&count=6&volume=0.0&pull_type=2&need_relieve_aweme=0&filter_warn=0&req_from&is_cold_start=0'
- return self.__http_get(douyin_url)
- def get_nearby_feed(self, city_id):
- """获取对应城市的推荐列表
- :param cityid: 城市代码, 从https://wenku.baidu.com/view/af4281bafd0a79563c1e7287.html获取
- :return:
- """
- params = {
- 'city': city_id,
- }
- douyin_url = 'https://api.amemv.com/aweme/v1/nearby/feed/?max_cursor=0&min_cursor=0&count=20&feed_style=1&filter_warn=0&poi_class_code=0'
- return self.__http_get(douyin_url, params)
- def get_user_info(self, user_id):
- """获取用户信息
- :param user_id: 用户ID
- :return:
- """
- params = {
- 'user_id': user_id
- }
- douyin_url = 'https://aweme-eagle.snssdk.com/aweme/v1/user/?'
- return self.__http_get(douyin_url, params)
- def get_room_flv(self, room_id):
- """获取用户信息
- :param user_id: 用户ID
- :return:
- """
- params = {
- 'room_id': room_id,
- 'live_id':'1'
- }
- douyin_url = 'https://webcast-hl.amemv.com/webcast/room/reflow/info/?'
- return self.__http_get(douyin_url, params)
- def get_user_post(self, user_id, max_cursor, count):
- """获取用户作品
- :param user_id: 用户ID
- :param max_cursor: 用于分页,第1页是0,后1页是上1页请求的时候返回的max_cursor
- :param count: 返回视频的条数
- :return:
- """
- params = {
- 'user_id': user_id,
- 'max_cursor': str(max_cursor),
- 'count': str(count)
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/aweme/post/'
- return self.__http_get(douyin_url, params)
- def comm_get(self, douyin_url, params):
- """获取用户信息
- :param user_id: 用户ID
- :return:
- """
- return self.__http_get(douyin_url, params)
- def get_sec_user_favorite(self, sec_user_id, max_cursor, count):
- """获取用户作品
- :param user_id: 用户ID
- :param max_cursor: 用于分页,第1页是0,后1页是上1页请求的时候返回的max_cursor
- :param count: 返回视频的条数
- :return:
- """
- params = {
- 'sec_user_id': sec_user_id,
- 'max_cursor': str(max_cursor),
- 'count': str(count)
- }
- douyin_url = 'https://aweme-hl.snssdk.com/aweme/v1/aweme/favorite/?invalid_item_count=0&is_hiding_invalid_item=0&'
- return self.__http_get(douyin_url, params)
- def get_user_favorite(self, user_id, max_cursor, count):
- """获取用户作品
- :param user_id: 用户ID
- :param max_cursor: 用于分页,第1页是0,后1页是上1页请求的时候返回的max_cursor
- :param count: 返回视频的条数
- :return:
- """
- params = {
- 'user_id': user_id,
- 'max_cursor': str(max_cursor),
- 'count': str(count)
- }
- douyin_url = 'https://aweme-hl.snssdk.com/aweme/v1/aweme/favorite/?invalid_item_count=0&is_hiding_invalid_item=0&'
- return self.__http_get(douyin_url, params)
- def get_user_forward_list(self, user_id, max_cursor, count):
- """获取用户动态
- :param user_id: 用户ID
- :param max_cursor: 用于分页,第1页是0,后1页是上1页请求的时候返回的max_cursor
- :param count: 每次返回的动态条数
- :return:
- """
- params = {
- 'user_id': user_id,
- 'max_cursor': str(max_cursor),
- 'count': str(count)
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/forward/list/'
- return self.__http_get(douyin_url, params)
- def get_user_following_list(self, user_id, max_time, count):
- """获取用户关注列表 注意:关注列表请求太频繁会导致不返回数据
- :param user_id: 用户ID
- :param max_time: 用于分页,第1页是0,后1页是上1页请求时返回的min_time
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'user_id': user_id,
- 'max_time': str(int(time.time()) if max_time == 0 else max_time),
- 'count': str(count),
- 'source_type': '1'
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/user/following/list/'
- return self.__http_get(douyin_url, params)
- def get_user_follower_list(self, user_id, min_time, count):
- """获取用户粉丝列表
- :param user_id: 用户ID
- :param min_time: 用于分页,第1页是0,后1页是上1页请求时返回的min_time
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'user_id': user_id,
- 'max_time': str(int(time.time()) if min_time == 0 else min_time),
- 'count': str(count)
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/user/follower/list/'
- return self.__http_get(douyin_url, params)
- def get_user_favorite_list(self, user_id, min_time, count):
- """获取用户粉丝列表
- :param user_id: 用户ID
- :param min_time: 用于分页,第1页是0,后1页是上1页请求时返回的min_time
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'user_id': user_id,
- 'max_time': str(int(time.time()) if min_time == 0 else min_time),
- 'count': str(count)
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/user/follower/list/'
- return self.__http_get(douyin_url, params)
- def get_hot_search_list(self):
- """获取抖音热搜榜
- :return:
- """
- douyin_url = 'https://api.amemv.com/aweme/v1/hot/search/list/?detail_list=1'
- return self.__http_get(douyin_url)
- def get_hot_video_list(self):
- """获取抖音视频榜
- :return:
- """
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/hotsearch/aweme/billboard/'
- return self.__http_get(douyin_url)
- def get_hot_music_list(self):
- """获取抖音音乐榜
- :return:
- """
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/hotsearch/music/billboard/'
- return self.__http_get(douyin_url)
- def get_hot_positive_energy_list(self):
- """获取抖音正能量榜
- :return:
- """
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/hotsearch/positive_energy/billboard/'
- return self.__http_get(douyin_url)
- def get_hot_category_list(self, cursor, count):
- """获取热门分类列表
- :param cursor: 分页用,第1页是0,下一页是上1页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'cursor': str(cursor),
- 'count': str(count)
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/category/list/'
- return self.__http_get(douyin_url, params)
- def general_search(self, keyword, offset, count):
- """综合搜索
- :param keyword: 关键词
- :param offset: 分页,第1页是0,下1页是上1页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'keyword': keyword,
- 'offset': str(offset),
- 'count': str(count),
- 'is_pull_refresh': '0',
- 'hot_search': '0',
- 'latitude': '0.0',
- 'longitude': '0.0'
- }
- douyin_url = 'https://aweme-hl.snssdk.com/aweme/v1/general/search/single/?'
- return self.__http_post(douyin_url, params)
- def item_search(self, keyword, offset, count):
- """综合搜索
- :param keyword: 关键词
- :param offset: 分页,第1页是0,下1页是上1页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'query': keyword,
- 'cursor': str(offset),
- 'count': str(count),
- 'request_type': '1',
- 'search_filter': '1',
- 'search_source': 'commodity_search',
- 'enter_from': 'homepage_hot'
- }
- douyin_url = 'https://api5-normal-c-hl.amemv.com/aweme/v2/shop/search/aggregate/shopping/?'
- return self.__http_post(douyin_url, params)
- def video_search(self, keyword, offset, count):
- """ 视频搜索
- :param keyword: 关键词
- :param offset: 分页,第1页是0,下1页是上1页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'keyword': keyword,
- 'offset': str(offset),
- 'count': str(count),
- 'is_pull_refresh': '0',
- 'hot_search': '0',
- 'source': 'video_search'
- }
- douyin_url = 'https://aweme-hl.snssdk.com/aweme/v1/search/item/?'
- return self.__http_post(douyin_url, params)
- def user_search(self, keyword, offset, count):
- """ 用户搜索
- :param keyword: 关键词
- :param offset: 分页,第1页是0,下1页是上1页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'keyword': keyword,
- 'cursor': str(offset),
- 'count': str(count),
- 'type': '1',
- 'is_pull_refresh': '0',
- 'hot_search': '0',
- 'source': ''
- }
- douyin_url = 'https://aweme-hl.snssdk.com/aweme/v1/discover/search/?'
- return self.__http_post(douyin_url, params)
- def get_video_comment_list(self, aweme_id, cursor, count):
- """获取视频评论列表
- :param awemeId: 视频ID
- :param cursor: 分页, 第1页是0, 下1页是上1页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'aweme_id': aweme_id,
- 'cursor': str(cursor),
- 'count': str(count)
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v2/comment/list/'
- return self.__http_get(douyin_url, params)
- def get_video_detail(self, aweme_id):
- """获取视频详情
- :param aweme_id: 视频ID
- :return:
- """
- params = {
- 'aweme_id': aweme_id
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/aweme/detail/'
- return self.__http_get(douyin_url, params)
- def get_music_detail(self, music_id):
- """获取音乐详情
- :param music_id: 音乐id
- :return:
- """
- params = {
- 'music_id': str(music_id),
- 'click_reason': '0'
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/music/detail/'
- return self.__http_get(douyin_url, params)
- def get_music_videos(self, music_id, cursor, count):
- """获取音乐对应的视频列表
- :param music_id: 音乐id
- :param cursor: 分页,首页是0,下一页是上一页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'music_id': str(music_id),
- 'cursor': str(cursor),
- 'count': str(count),
- 'type': '6'
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/music/aweme/'
- return self.__http_get(douyin_url, params)
- def get_topic_videos(self, hashtag_name, cursor, count):
- """获取话题相关视频
- :param hashtag_name: 话题
- :param cursor: 分页,首页是0,下一页是上一页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- 'cursor': str(cursor),
- 'count': str(count),
- 'source': 'challenge_video',
- 'hashtag_name': hashtag_name,
- 'type': '5',
- 'query_type': '1'
- }
- douyin_url = 'https://aweme-hl.snssdk.com/aweme/v1/challenge/aweme/'
- return self.__http_get(douyin_url, params)
- def get_promotion_list(self, user_id,sec_user_id, cursor, count):
- """获取商品橱窗列表
- :param user_id: user id
- :param cursor: 分页,首页是0,下一页是上一页请求返回的cursor
- :param count: 每次返回的条数
- :return:
- """
- params = {
- # 'sec_user_id':sec_user_id,
- 'count': str(count),
- 'cursor': str(cursor),
- 'user_id': str(user_id),
- 'retry_type': 'no_retry',
- 'ac': '4g',
- 'channel': channel,
- 'aid': '2329',
- 'app_name': 'aweme',
- 'version_code': f'{V1}{V2}0',
- 'version_name': f'{V1}.{V2}.0',
- 'device_platform': 'android',
- 'ssmix': 'a',
- 'device_type': device_type,
- 'device_brand': device_brand,
- 'language': 'zh',
- 'os_api': '25',
- 'os_version': '7.1.2',
- 'manifest_version_code': f'{V1}{V2}0',
- 'resolution': '720*1280',
- 'dpi': '192',
- 'update_version_code': f'{V1}{V2}02',
- 'mcc_mnc': '46000'
- }
- douyin_url = 'https://aweme.snssdk.com/aweme/v1/promotion/user/promotion/list/'
- return self.__http_get(douyin_url, params)
- def get_share_video_detail(self, share_url):
- """获取分享链接对应的视频信息
- :param share_url: 分享链接
- :return:
- """
- headers = {
- 'Accept': '*/*',
- 'Connection': 'keep-alive',
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
- }
- resp = requests.get(share_url, headers=headers, timeout=20)
- url_path = parse.urlparse(resp.url).path
- video_id = url_path.split('/')[3]
- return self.get_video_detail(video_id)
- def get_webcast_room_info(self, room_id):
- """获取直播房间信息
- :param room_id:
- :return:
- """
- params = {
- 'pack_level': '4',
- 'room_id': str(room_id),
- 'webcast_sdk_version': '1710'
- }
- douyin_url = 'https://webcast.amemv.com/webcast/room/info/?'
- return self.__http_get(douyin_url, params)
- def get_webcast_user_info(self, room_id, user_id):
- """获取直播用户信息
- :param user_id:
- :return:
- """
- params = {
- 'request_from': 'admin',
- 'current_room_id': str(room_id),
- 'target_uid': str(user_id),
- 'anchor_id': str(user_id),
- 'packed_level': '2',
- 'webcast_sdk_version': '1150'
- }
- douyin_url = 'https://webcast.amemv.com/webcast/user/'
- return self.__http_get(douyin_url, params)
- def get_webcast_ranklist(self, room_id):
- """获取直播本场榜
- :param room_id:
- :param anchor_id:
- :return:
- """
- params = {
- 'room_id': str(room_id),
- 'rank_type': '17',
- 'webcast_sdk_version': '1150'
- }
- douyin_url = 'https://webcast.amemv.com/webcast/ranklist/room/' + str(room_id) + '/contributor/'
- return self.__http_get(douyin_url, params)
- def __get_random(self, len):
- return ''.join(str(random.choice(range(10))) for _ in range(len))
- def __get_msg(self, resp):
- return json.loads(resp.text)['msg']
- def __get_random_mac(self):
- mac = [0x10, 0x2a, 0xb3,
- random.randint(0x00, 0x7f),
- random.randint(0x00, 0xff),
- random.randint(0x00, 0xff)]
- return ':'.join(map(lambda x: "%02x" % x, mac))
- def __add_other_params(self, douyin_url, params=None):
- if params is None:
- params = {}
- if not douyin_url.__contains__('?'):
- douyin_url = douyin_url + '?'
- common_params = parse.urlencode(self.__device_params)
- if douyin_url.endswith('?') or douyin_url.endswith('&'):
- douyin_url = douyin_url + common_params
- else:
- douyin_url = douyin_url + '&' + common_params
- if len(params) > 0:
- douyin_url = douyin_url + '&' + parse.urlencode(params)
- douyin_url = douyin_url + "&_rticket=" + str(int(round(time.time() * 1000))) + "&ts=" + str(int(time.time()))
- return douyin_url
- def __get_cookie(self):
- if len(self.__cookie) == 0:
- return ''
- return "; ".join([str(x) + "=" + str(y) for x, y in self.__cookie.items()])
- def get_webcast_feed(self):
- params = {
- }
- douyin_url = 'https://webcast.amemv.com/webcast/feed/?'
- return self.__http_get(douyin_url, params)
- def __get_sign(self, url, form_params=None):
- stub = ''
- if form_params:
- a = parse.urlencode(form_params)
- stub = hashlib.md5(a.encode('utf-8')).hexdigest()
- ts = int(time.time())
- from libs.Xg04 import X_Gorgon
- params = url[url.index('?') + 1:]
- result = X_Gorgon(params, "", cookie)
- gorgon = result['X-Gorgon']
- # ppp = url[url.index('?') + 1:]
- # s = getXGon(ppp, stub, parse.urlencode(self.__cookie))
- # gorgon = xGorgon(ts, strToByte(s))
- #
- # data = {"url": url, "headers": {}}
- # gorgon = requests.post("http://121.36.217.134:18500/gorgon", data=str(data)).text
- sign = {
- 'X-Khronos': str(ts),
- 'X-Gorgon': gorgon,
- 'X-Pods': ''
- }
- # print(gorgon)
- if stub:
- sign.update({
- 'X-SS-STUB': stub.upper()
- })
- return sign
- def __get_headers(self, sign=None):
- if sign is None:
- sign = {}
- headers = {
- 'User-Agent': DouYinApi.USER_AGENT,
- 'X-SS-REQ-TICKET': str(round(time.time() * 1000)),
- # 'response-format':'protobuf'
- }
- headers.update(sign)
- return headers
- def __http_get(self, url, query_params=None):
- if query_params is None:
- query_params = {}
- url = self.__add_other_params(url, query_params)
- # print(url)
- sign = self.__get_sign(url)
- if self.proxies:
- resp = requests.get(url, headers=self.__get_headers(sign), cookies=self.__cookie, proxies=self.proxies,
- verify=False, timeout=20)
- else:
- resp = requests.get(url, headers=self.__get_headers(sign), cookies=self.__cookie, verify=False, timeout=20)
- cookie = resp.cookies.get_dict()
- if len(cookie) != 0:
- self.__cookie.update(cookie)
- # print(resp.text[:])
- return resp.json()
- def __http_post(self, url, form_params=None):
- if form_params is None:
- form_params = {}
- url = self.__add_other_params(url)
- sign = self.__get_sign(url, form_params)
- if self.proxies:
- resp = requests.post(url, headers=self.__get_headers(sign), data=form_params, cookies=self.__cookie, proxies=self.proxies,
- verify=False, timeout=20)
- else:
- resp = requests.post(url, headers=self.__get_headers(sign), data=form_params, cookies=self.__cookie,
- verify=False, timeout=20)
- cookie = resp.cookies.get_dict()
- if len(cookie) != 0:
- self.__cookie.update(cookie)
- # print(resp.text)
- return resp.text
- def comm_get(self, douyin_url, params={}, need_comm_param=True):
- """获取用户信息
- :param user_id: 用户ID
- :return:
- """
- if need_comm_param:
- return self.__http_get(douyin_url, params)
- else:
- params = parse.urlencode(params)
- url = douyin_url + params
- sign = self.__get_sign(douyin_url)
- if self.proxies:
- resp = requests.get(url, headers=self.__get_headers(sign), cookies=self.__cookie, proxies=self.proxies,
- verify=False, timeout=20)
- else:
- resp = requests.get(url, headers=self.__get_headers(sign), cookies=self.__cookie, verify=False, timeout=20)
- cookie = resp.cookies.get_dict()
- if len(cookie) != 0:
- self.__cookie.update(cookie)
- # print(resp.text)
- return resp.text
- def get_room_product_list(self, room_id, anchor_id, sec_author_id):
- """
- 获取直播间商品信息
- :return:
- """
- params = {
- 'room_id': str(room_id),
- 'anchor_id': str(anchor_id),
- 'sec_author_id': sec_author_id,
- }
- douyin_url = 'https://lianmengapi.snssdk.com/live/promotions/?'
- return self.__http_get(douyin_url, params)
- def get_product_info(self, promotion_id, product_id, author_id):
- """
- 获取商品信息
- :param promotion_id:商品id
- :return:
- """
- params = {
- "promotion_id": promotion_id,
- "product_id": product_id,
- "author_id": author_id,
- }
- douyin_url = 'https://api3-normal-c-lf.amemv.com/aweme/v2/shop/promotion/'
- return self.__http_post(douyin_url, params)
- def get_room_product_campaign(self, promotion_id):
- """
- 获取直播间商品信息
- :return:
- """
- params = {
- 'promotion_ids': str(promotion_id),
- }
- douyin_url = 'https://lianmengapi.snssdk.com/live/promotion/campaign/?'
- return self.__http_get(douyin_url, params)
- def getDevice(self):
- result = self.register_device()
- # print(result)
- device_id, iid, udid, openudid, cookie = result['device_id'], result['iid'], result['uuid'], result['openudid'], result['cookie']
- if device_id == '0':
- return '2532904814256759', '3166223513429303'
- self.init_device_ids(device_id, iid, udid, openudid)
- params = {
- "has_market": "0",
- "is_activated": '0'
- }
- self.comm_get('https://aweme.snssdk.com/service/2/app_alert/?', params)
- return device_id, iid
- if __name__ == '__main__':
- import warnings
- warnings.filterwarnings("ignore")
- for i in range(30):
- proxy = Proxy.get_yuanrenyun_list()
- print(proxy)
- proxies = {
- "http": "http://" + proxy,
- "https": "http://" + proxy
- }
- douApi = DouYinApi('', proxies)
- for i in range(10):
- try:
- result = douApi.register_device()
- print(result)
- device_id, iid, udid, openudid, cookie, cdid = result['device_id'], result['iid'], result['uuid'], \
- result['openudid'], result['cookie'], result['clientudid']
- if device_id == '0':
- continue
- douApi.init_device_ids(device_id, iid, udid, openudid)
- params = {
- "has_market": "0",
- "is_activated": '0'
- }
- douApi.comm_get('https://aweme.snssdk.com/service/2/app_alert/?', params)
- server_time = str(int(time.time()))
- data = device_id + '@@@' + iid + '@@@' + openudid + '@@@' + udid + '@@@' + cookie + '@@@' + server_time + '@@@' + cdid + '@@@' + proxy + '@@@' + V1 + '@@@' + V2 + '@@@' + device_type + '@@@' + device_brand
- print(data)
- key = 'DOUYIN_SCRAPE_DID_IID_TTREQ_0414'
- redis = DbRedis.kwai_connect().lpush(key, data)
- key = 'DOUYIN_SCRAPE_DID_IID_TTREQ_1221'
- if i > 10:
- key = 'DOUYIN_SCRAPE_DID_IID_TTREQ_1221C'
- redis = DbRedis.kwai_connect().lpush(key, data)
- except Exception as e:
- print(e)
- continue
|