X-bogus python实现

直接上代码

import requests
import time
import json
import hashlib
import base64
import pandas as pd
import re


url = 'https://www.douyin.com/aweme/v1/web/aweme/detail/?'
# 二选一
cookie = r's_v_web_id=verify_lmzydfdb_dtOkZ4fO_5jE9_4dlp_9bj7_GWF0F7uMSTAr; passport_csrf_token=828ccb53df8c19c996dba2928bb8c264; passport_csrf_token_default=828ccb53df8c19c996dba2928bb8c264; n_mh=e4x5jqdtfkdY7w4-3d7fXEa9Ey-4gO3YqukXhRn8jxk; sso_uid_tt=867a5f26659e2c98010d8caa72407eb7; sso_uid_tt_ss=867a5f26659e2c98010d8caa72407eb7; toutiao_sso_user=e71286ac7f31eaa403f5f295b6d415f5; toutiao_sso_user_ss=e71286ac7f31eaa403f5f295b6d415f5; passport_auth_status=2c34ec49e904a1792dcf5c5653ab5f4f%2C; passport_auth_status_ss=2c34ec49e904a1792dcf5c5653ab5f4f%2C; uid_tt=5e7ce70b356bee09d8046e0101cdb03f; uid_tt_ss=5e7ce70b356bee09d8046e0101cdb03f; sid_tt=8ad075c908f45ae23cd5fcbadc9abcbc; sessionid=8ad075c908f45ae23cd5fcbadc9abcbc; sessionid_ss=8ad075c908f45ae23cd5fcbadc9abcbc; passport_assist_user=CkFNobWL3orDkI-QUh6FZXoOLTk9T4ZOWotobFxrtHsiD4vxrwSvT2vbCXXKyBWFopOF_pRZGrWRQg1OJ02WFEFuKBpKCjzHDQiqNtrN59KPE14ta_jUxG1J6v3EgJNPY8bvFcWvA9sSKf7QXXsVhTbEeJh-SEdUuIvm8QIoJLY8Id8Q-fm8DRiJr9ZUIAEiAQPoxray; sid_ucp_sso_v1=1.0.0-KDY5Yjc4YmE1MWRlYTk0OTY3NmExZWNjZGM1ZWZjNTFjNTg4NmY4ZTQKHwid1rCYyIyZBBCN_cmoBhjvMSAMMO3goJIGOAZA9AcaAmhsIiBlNzEyODZhYzdmMzFlYWE0MDNmNWYyOTViNmQ0MTVmNQ; ssid_ucp_sso_v1=1.0.0-KDY5Yjc4YmE1MWRlYTk0OTY3NmExZWNjZGM1ZWZjNTFjNTg4NmY4ZTQKHwid1rCYyIyZBBCN_cmoBhjvMSAMMO3goJIGOAZA9AcaAmhsIiBlNzEyODZhYzdmMzFlYWE0MDNmNWYyOTViNmQ0MTVmNQ; LOGIN_STATUS=1; store-region=cn-ha; store-region-src=uid; _bd_ticket_crypt_doamin=3; _bd_ticket_crypt_cookie=fc0fa039d2ee2baff7305d043ebd7b7f; __security_server_data_status=1; d_ticket=9f1c48286ec048841453de7f36ca0b8efc622; sid_guard=8ad075c908f45ae23cd5fcbadc9abcbc%7C1695710887%7C5183976%7CSat%2C+25-Nov-2023+06%3A47%3A43+GMT; sid_ucp_v1=1.0.0-KGJkOGNkMDM1N2VmODk4N2NkNjU2ZGM0MGZkNmQzMWFkZjI5NjZiMDQKGwid1rCYyIyZBBCn_cmoBhjvMSAMOAZA9AdIBBoCbGYiIDhhZDA3NWM5MDhmNDVhZTIzY2Q1ZmNiYWRjOWFiY2Jj; ssid_ucp_v1=1.0.0-KGJkOGNkMDM1N2VmODk4N2NkNjU2ZGM0MGZkNmQzMWFkZjI5NjZiMDQKGwid1rCYyIyZBBCn_cmoBhjvMSAMOAZA9AdIBBoCbGYiIDhhZDA3NWM5MDhmNDVhZTIzY2Q1ZmNiYWRjOWFiY2Jj; ttwid=1%7Cj4zs9rPOs3X3cMrKBtgcSIV0WyzAOlgVg4n6Jwx3Ksw%7C1696490848%7Ca716a36aa44fad9bdc82f5565ddf34f470dc007daae3bcf82245f3850890499d; publish_badge_show_info=%220%2C0%2C0%2C1696513191237%22; volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Atrue%2C%22volume%22%3A0.5%7D; SEARCH_RESULT_LIST_TYPE=%22single%22; odin_tt=38f009b093bf5909bd215620b461c72a7a1483c86b67c43d6e71c638a3759abf87b4eb1f1536eafe82b74864249be27a; __ac_nonce=06520a9ea003d6c729601; __ac_signature=_02B4Z6wo00f016ug7KgAAIDCIOt3SrWVc6-rgOgAAI.RVzJPQo7yOim1zYDfWBiGMurl2MIItRaCqC72-yUEWfi8aiuvV4nJg1kcibUSPi2ZARnPGdy6GinfzEbnzugquwvy1B2QZB0Lfrop62; strategyABtestKey=%221696639469.443%22; pwa2=%220%7C0%7C1%7C0%22; download_guide=%223%2F20231007%2F1%22; douyin.com; device_web_cpu_core=8; device_web_memory_size=8; architecture=amd64; webcast_local_quality=null; home_can_add_dy_2_desktop=%220%22; VIDEO_FILTER_MEMO_SELECT=%7B%22expireTime%22%3A1697245289063%2C%22type%22%3A1%7D; passport_fe_beating_status=true; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCS1cxbzlxcUl3UFNiU3dyT01pSHY1azRnaHIyenVBTGliY1hBTUEvaDJDVlEwT3hZRyt5cm9XeUcwa2NwZkYyUVJyc3plcUpJWURZKzNXdTROdzIwT009IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoxfQ%3D%3D; tt_scid=PteXa1GG1FCZNHBdMuyeWNWjYExBzJBmiW.IQxUwBssN28w7dt-Uzwwy.MJb-QXh36f3; csrf_session_id=70f907965f8bd3b020966de9c6411d15; msToken=H5BxriiIivOl5UUU0mXLEnjCKfz7Ca2gKQRJCv914YWhu4bVv7yZ82XNoruiBa6XiRf2UID6pF8pP8YdccU90f5esqV3M3xcQ0tio7x51woEmlZB1Ws=; msToken=dZHGrjFIKoitQqYjt-sKlKyAzoc_1MRoBSwqiZkIwc9pUthcTEIrUH8KnrgHcSFcgu9AGk2yQPsF51bFWjA5OCLGhDoSxsZCqsKNl_14SqbG6Qm64vI=; IsDouyinActive=false; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1536%2C%5C%22screen_height%5C%22%3A864%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A8%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A50%7D%22'
msToken="1cFOpHXwWpFPGAefDs5KY472KsN2dyBItRSqa_jgNUbxVw7VNi09h1SBfFWuJgjeRxbl4bMp6-HBcIKxDV5JcQUcyIvE44kpSiIZv6EFCphZnkIiBtw="
ttwid="1%7Cj4zs9rPOs3X3cMrKBtgcSIV0WyzAOlgVg4n6Jwx3Ksw%7C1696490848%7Ca716a36aa44fad9bdc82f5565ddf34f470dc007daae3bcf82245f3850890499d"


ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'
# # 失效
# def generate_random_str(randomlength=16):
#         """
#         根据传入长度产生随机字符串
#         """
#         random_str = ''
#         base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789='
#         length = len(base_str) - 1
#         for _ in range(randomlength):
#             random_str += base_str[random.randint(0, length)]
#         return random_str

# def getttwid():
#     url = 'https://ttwid.bytedance.com/ttwid/union/register/'
#     data = '{"region":"cn","aid":1768,"needFid":false,"service":"www.ixigua.com","migrate_info":{"ticket":"","source":"node"},"cbUrlProtocol":"https","union":true}'
#     res = requests.post(url=url, data=data)
#     for i, j in res.cookies.items():
#         return j

douyin_headers = {
    'User-Agent': ua,
    'referer': 'https://www.douyin.com/',
    'accept-encoding': None,
    # 'Cookie': cookie,
    'Cookie': f"msToken={msToken}; ttwid={ttwid}; odin_tt=324fb4ea4a89c0c05827e18a1ed9cf9bf8a17f7705fcc793fec935b637867e2a5a9b8168c885554d029919117a18ba69; passport_csrf_token=f61602fc63757ae0e4fd9d6bdcee4810;"
    # 'Cookie': f"msToken={generate_random_str(107)}; ttwid={getttwid()}; odin_tt=324fb4ea4a89c0c05827e18a1ed9cf9bf8a17f7705fcc793fec935b637867e2a5a9b8168c885554d029919117a18ba69; passport_csrf_token=f61602fc63757ae0e4fd9d6bdcee4810;"
}

def getShareLink(string):
        # findall() 查找匹配正则表达式的字符串
        return re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', string)[0]

    # 得到 作品id 或者 用户id
    # 传入 url 支持 https://www.iesdouyin.com 与 https://v.douyin.com

def getAweme(url):
    key = None
    key_type = None

    try:
        r = requests.get(url=url, headers=douyin_headers)
    except Exception as e:
        print('[  错误  ]:输入链接有误!\r')
        return key_type, key

    # 抖音把图集更新为note
    # 作品 第一步解析出来的链接是share/video/{aweme_id}
    # https://www.iesdouyin.com/share/video/7037827546599263488/?region=CN&mid=6939809470193126152&u_code=j8a5173b&did=MS4wLjABAAAA1DICF9-A9M_CiGqAJZdsnig5TInVeIyPdc2QQdGrq58xUgD2w6BqCHovtqdIDs2i&iid=MS4wLjABAAAAomGWi4n2T0H9Ab9x96cUZoJXaILk4qXOJlJMZFiK6b_aJbuHkjN_f0mBzfy91DX1&with_sec_did=1&titleType=title&schema_type=37&from_ssr=1&utm_source=copy&utm_campaign=client_share&utm_medium=android&app=aweme
    # 用户 第一步解析出来的链接是share/user/{sec_uid}
    # https://www.iesdouyin.com/share/user/MS4wLjABAAAA06y3Ctu8QmuefqvUSU7vr0c_ZQnCqB0eaglgkelLTek?did=MS4wLjABAAAA1DICF9-A9M_CiGqAJZdsnig5TInVeIyPdc2QQdGrq58xUgD2w6BqCHovtqdIDs2i&iid=MS4wLjABAAAAomGWi4n2T0H9Ab9x96cUZoJXaILk4qXOJlJMZFiK6b_aJbuHkjN_f0mBzfy91DX1&with_sec_did=1&sec_uid=MS4wLjABAAAA06y3Ctu8QmuefqvUSU7vr0c_ZQnCqB0eaglgkelLTek&from_ssr=1&u_code=j8a5173b&timestamp=1674540164&ecom_share_track_params=%7B%22is_ec_shopping%22%3A%221%22%2C%22secuid%22%3A%22MS4wLjABAAAA-jD2lukp--I21BF8VQsmYUqJDbj3FmU-kGQTHl2y1Cw%22%2C%22enter_from%22%3A%22others_homepage%22%2C%22share_previous_page%22%3A%22others_homepage%22%7D&utm_source=copy&utm_campaign=client_share&utm_medium=android&app=aweme
    # 合集
    # https://www.douyin.com/collection/7093490319085307918
    urlstr = str(r.request.path_url)
    if "/video/" in urlstr:
        # 获取作品 aweme_id
        key = re.findall('video/(\d+)?', urlstr)[0]
        key_type = "aweme"
    elif "/note/" in urlstr:
        # 获取note aweme_id
        key = re.findall('note/(\d+)?', urlstr)[0]
        key_type = "aweme"
    return key_type, key

def getXbogus(payload, form='', ua=ua):
        xbogus = get_xbogus(payload, ua, form)
        params = payload + "&X-Bogus=" + xbogus
        return params

def _0x30492c(a, b):
        d = [i for i in range(256)]
        c = 0
        result = bytearray(len(b))

        for i in range(256):
            c = (c + d[i] + ord(a[i % len(a)])) % 256
            e = d[i]
            d[i] = d[c]
            d[c] = e

        t = 0
        c = 0

        for i in range(len(b)):
            t = (t + 1) % 256
            c = (c + d[t]) % 256
            e = d[t]
            d[t] = d[c]
            d[c] = e
            result[i] = ord(b[i]) ^ d[(d[t] + d[c]) % 256]

        return result

def get_arr2(payload, ua, form):
        salt_payload_bytes = hashlib.md5(hashlib.md5(payload.encode()).digest()).digest()
        salt_payload = [byte for byte in salt_payload_bytes]

        salt_form_bytes = hashlib.md5(hashlib.md5(form.encode()).digest()).digest()
        salt_form = [byte for byte in salt_form_bytes]

        ua_key = ['\u0000', '\u0001', '\u000e']
        salt_ua_bytes = hashlib.md5(base64.b64encode(_0x30492c(ua_key, ua))).digest()
        salt_ua = [byte for byte in salt_ua_bytes]

        timestamp = int(time.time())
        canvas = 1489154074

        arr1 = [
            64,  # 固定
            0,  # 固定
            1,  # 固定
            14,  # 固定 这个还要再看一下,14,12,0都出现过
            salt_payload[14],  # payload 相关
            salt_payload[15],
            salt_form[14],  # form 相关
            salt_form[15],
            salt_ua[14],  # ua 相关
            salt_ua[15],
            (timestamp >> 24) & 255,
            (timestamp >> 16) & 255,
            (timestamp >> 8) & 255,
            (timestamp >> 0) & 255,
            (canvas >> 24) & 255,
            (canvas >> 16) & 255,
            (canvas >> 8) & 255,
            (canvas >> 0) & 255,
            64,  # 校验位
        ]

        for i in range(1, len(arr1) - 1):
            arr1[18] ^= arr1[i]

        arr2 = [arr1[0], arr1[2], arr1[4], arr1[6], arr1[8], arr1[10], arr1[12], arr1[14], arr1[16], arr1[18], arr1[1],
                arr1[3], arr1[5], arr1[7], arr1[9], arr1[11], arr1[13], arr1[15], arr1[17]]

        return arr2

def get_garbled_string(arr2):
        p = [
            arr2[0], arr2[10], arr2[1], arr2[11], arr2[2], arr2[12], arr2[3], arr2[13], arr2[4], arr2[14],
            arr2[5], arr2[15], arr2[6], arr2[16], arr2[7], arr2[17], arr2[8], arr2[18], arr2[9]
        ]

        char_array = [chr(i) for i in p]
        f = []
        f.extend([2, 255])
        tmp = ['ÿ']
        bytes_ = _0x30492c(tmp, "".join(char_array))

        for i in range(len(bytes_)):
            f.append(bytes_[i])

        return f

def get_xbogus(payload, ua, form):
        short_str = "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe="
        arr2 = get_arr2(payload, ua, form)

        garbled_string = get_garbled_string(arr2)

        xbogus = ""

        for i in range(0, 21, 3):
            char_code_num0 = garbled_string[i]
            char_code_num1 = garbled_string[i + 1]
            char_code_num2 = garbled_string[i + 2]
            base_num = char_code_num2 | char_code_num1 << 8 | char_code_num0 << 16
            str1 = short_str[(base_num & 16515072) >> 18]
            str2 = short_str[(base_num & 258048) >> 12]
            str3 = short_str[(base_num & 4032) >> 6]
            str4 = short_str[base_num & 63]
            xbogus += str1 + str2 + str3 + str4

        return xbogus

def getAwemeInfoApi(aweme_id):
        if aweme_id is None:
            return None
        start = time.time()  # 开始时间
        while True:
            try:
                jx_url = url + getXbogus(
                    f'aweme_id={aweme_id}&device_platform=webapp&aid=6383')

                raw = requests.get(url=jx_url, headers=douyin_headers).text
                datadict = json.loads(raw)
                if datadict is not None and datadict["status_code"] == 0:
                    return datadict
            except Exception as e:
                end = time.time()  # 结束时间
                if end - start > 10:
                    return None

def get_data(aweme_id):
    vedio_info  = getAwemeInfoApi(aweme_id)
    if vedio_info is None: return
    detail = vedio_info.get('aweme_detail', None)
    if detail is None: return
    likes = vedio_info['aweme_detail']['statistics']['digg_count']
    comments = vedio_info['aweme_detail']['statistics']['comment_count']
    collects = vedio_info['aweme_detail']['statistics']['collect_count']
    shares = vedio_info['aweme_detail']['statistics']['share_count']
    return likes, comments, collects, shares

def main():
    excel_dir = input('请输入要生成的Excel文件路径:')
    excel_dir = re.findall("'(.*?)'", excel_dir)[0]
    def get_excel_data(excel_dir):
        for i in range(3):
            try:
                excel_data = pd.read_excel(excel_dir, header=i)
                print(excel_data.columns)
                if "视频链接" in excel_data.columns:
                    return excel_data
            except Exception as e:
                print(e)
                continue
        print("没有找到视频链接,Excel文件读取失败!")
    excel_data = get_excel_data(excel_dir)
    if excel_data is None: return
    for i in ['点赞数','评论数', '收藏数', '分享数']:
        if i not in excel_data.columns: excel_data[i] = pd.Series(dtype='object')
    for index, row in excel_data.iterrows():
        if type(row['点赞数']) == int: continue
        if pd.isna(row['视频链接']): continue
        else: atype, aweme_id = getAweme(row['视频链接'])
        if aweme_id is None: continue
        likes, comments, collects, shares = get_data(aweme_id)
        if likes is None: continue
        excel_data.loc[index, '点赞数'] = likes
        excel_data.loc[index, '评论数'] = comments
        excel_data.loc[index, '收藏数'] = collects
        excel_data.loc[index, '分享数'] = shares
        print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}|  已完成{index+1}条数据, 共{len(excel_data)}条数据, 点赞数数:{likes}, 评论数:{comments}, 收藏数:{collects}, 分享数:{shares}。')
        excel_data.to_excel(excel_dir, index=False)
        time.sleep(2)

if __name__ == '__main__':
    # try:main()
    # except Exception as e: print("程序运行出错")
    print(getAwemeInfoApi('7241788860043250978'))
    # print(getAweme('https://v.douyin.com/UV9jBut/'))

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
X-Bogus是一个用于测试和模拟环境的虚拟服务器。本地部署X-Bogus意味着将X-Bogus服务器安装在本地环境中的计算机或服务器上。 首先,为了进行本地部署X-Bogus,我们需要获取X-Bogus的安装包或源代码。可以从官方网站或开源社区获取最新的X-Bogus版本。 接下来,我们需要在本地计算机或服务器上安装运行X-Bogus所需的软件和依赖项。具体的安装步骤可能因操作系统而异,但通常涉及以下几个步骤: 1. 安装并配置所需的运行环境,例如Node.js或其他运行X-Bogus的基础环境。 2. 解压或克隆X-Bogus的安装包或源代码到本地目录。 3. 打开终端或命令提示符,并导航至X-Bogus所在的目录。 4. 执行必要的命令或脚本以安装和配置X-Bogus。 一旦X-Bogus成功安装和配置在本地机器上,您可以根据需要进行自定义设置和调整。例如,您可以修改X-Bogus的配置文件以定义虚拟服务器的行为和响应。您还可以配置路由规则、设置特定的响应头和状态码等等。 在本地部署X-Bogus后,您可以使用它来模拟网络请求和响应,测试应用程序的各种场景和边界情况。您可以发送各种类型的请求,并模拟各种响应,以测试应用程序的鲁棒性和可靠性。 总结起来,本地部署X-Bogus需要获取安装包或源代码,安装运行X-Bogus所需的软件和依赖项,然后按照需要进行自定义设置和调整。这样,您便可以在本地环境中方便地使用X-Bogus来进行应用程序的测试和模拟。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值