diff --git a/TikTokApi/tiktok.py b/TikTokApi/tiktok.py
index a9e0ded3..7b133f8e 100644
--- a/TikTokApi/tiktok.py
+++ b/TikTokApi/tiktok.py
@@ -2,6 +2,7 @@
import requests
import time
import logging
+import json
from urllib.parse import urlencode, quote
from .browser import browser, get_playwright
from playwright import sync_playwright
@@ -154,7 +155,7 @@ def getData(self, **kwargs) -> dict:
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"user-agent": userAgent,
- "cookie": "tt_webid_v2=" + did,
+ "cookie": "tt_webid_v2=" + did + ';s_v_web_id=' + kwargs.get("custom_verifyFp", "verify_khgp4f49_V12d4mRX_MdCO_4Wzt_Ar0k_z4RCQC9pUDpX"),
},
proxies=self.__format_proxy(proxy),
)
@@ -685,6 +686,16 @@ def bySound(self, id, count=30, offset=0, **kwargs) -> dict:
def getMusicObject(self, id, **kwargs) -> dict:
"""Returns a music object for a specific sound id.
+ :param id: The sound id to search by.
+ :param language: The 2 letter code of the language to return.
+ Note: Doesn't seem to have an affect.
+ :param proxy: The IP address of a proxy to make requests from.
+ """
+ return self.getMusicObjectFull(id, **kwargs)['music']
+
+ def getMusicObjectFull(self, id, **kwargs):
+ """Returns a music object for a specific sound id.
+
:param id: The sound id to search by.
:param language: The 2 letter code of the language to return.
Note: Doesn't seem to have an affect.
@@ -697,14 +708,18 @@ def getMusicObject(self, id, **kwargs) -> dict:
maxCount,
did,
) = self.__process_kwargs__(kwargs)
- kwargs['custom_did'] = did
-
- query = {"musicId": id, "language": language}
- api_url = "{}node/share/music/{}?{}&{}".format(
- BASE_URL, self.get_music_title(id, **kwargs) + "-" + str(id), self.__add_new_params__(), urlencode(query)
- )
-
- return self.getData(url=api_url, **kwargs)
+ r = requests.get("https://www.tiktok.com/music/-{}".format(id), headers={
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "authority": "www.tiktok.com",
+ "Accept-Encoding": "gzip, deflate",
+ "Connection": "keep-alive",
+ "Host": "www.tiktok.com",
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
+ "Cookie": "s_v_web_id=" + kwargs.get("custom_verifyFp", "verify_khgp4f49_V12d4mRX_MdCO_4Wzt_Ar0k_z4RCQC9pUDpX"),
+ }, proxies=self.__format_proxy(kwargs.get("proxy", None)))
+ t = r.text
+ j_raw = t.split('")[0]
+ return json.loads(j_raw)['props']['pageProps']['musicInfo']
def byHashtag(self, hashtag, count=30, offset=0, **kwargs) -> dict:
"""Returns a dictionary listing TikToks with a specific hashtag.
@@ -999,14 +1014,22 @@ def getUser(self, username, **kwargs) -> dict:
maxCount,
did,
) = self.__process_kwargs__(kwargs)
- kwargs['custom_did'] = did
- secUid = self.get_secUid(username)
- query = {"uniqueId": username, "language": language, "isUniqueId": True, "validUniqueId": username, "sec_uid": "", "secUid": secUid}
- api_url = "{}node/share/user/@{}?{}&{}".format(
- BASE_URL, quote(username), self.__add_new_params__(), urlencode(query)
- )
+ r = requests.get("https://tiktok.com/@{}?lang=en".format(username), headers={
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "authority": "www.tiktok.com",
+ "path": "/{}".format(username),
+ "Accept-Encoding": "gzip, deflate",
+ "Connection": "keep-alive",
+ "Host": "www.tiktok.com",
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
+ "Cookie": "s_v_web_id=" + kwargs.get("custom_verifyFp", "verify_khgp4f49_V12d4mRX_MdCO_4Wzt_Ar0k_z4RCQC9pUDpX"),
+ }, proxies=self.__format_proxy(kwargs.get("proxy", None)))
- return self.getData(url=api_url, **kwargs)
+ t = r.text
+
+ j_raw = t.split('")[0]
+
+ return json.loads(j_raw)['props']['pageProps']
def getSuggestedUsersbyID(
self, userId="6745191554350760966", count=30, **kwargs
@@ -1334,14 +1357,24 @@ def get_Video_No_Watermark(self, video_url, return_bytes=0, **kwargs) -> bytes:
return r.content
def get_music_title(self, id, **kwargs):
- r = requests.get("https://www.tiktok.com/music/-{}".format(id), proxies=self.__format_proxy(kwargs.get("proxy", None)))
- text = r.text.split('TikTok","desc":')[0]
- on_tiktok = text.split(" | ")
- return on_tiktok[len(on_tiktok)-2].split(" ")[1]
+ r = requests.get("https://www.tiktok.com/music/-{}".format(id), headers={
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "authority": "www.tiktok.com",
+ "Accept-Encoding": "gzip, deflate",
+ "Connection": "keep-alive",
+ "Host": "www.tiktok.com",
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
+ "Cookie": "s_v_web_id=" + kwargs.get("custom_verifyFp", "verify_khgp4f49_V12d4mRX_MdCO_4Wzt_Ar0k_z4RCQC9pUDpX"),
+ }, proxies=self.__format_proxy(kwargs.get("proxy", None)))
+ t = r.text
+ j_raw = t.split('")[0]
+ return json.loads(j_raw)['props']['pageProps']['musicInfo']['title']
def get_secUid(self, username, **kwargs):
r = requests.get("https://tiktok.com/@{}?lang=en".format(username), headers={
- "Accept": "*/*",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "authority": "www.tiktok.com",
+ "path": "/{}".format(username),
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"Host": "www.tiktok.com",
diff --git a/setup.py b/setup.py
index 9925d388..a857e4cf 100644
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@
setuptools.setup(
name="TikTokApi",
packages=["TikTokApi"],
- version="3.7.8",
+ version="3.7.9",
license="MIT",
description="The Unofficial TikTok API Wrapper in Python 3.",
author="David Teather",