Skip to content

Commit

Permalink
Merge pull request #303 from davidteather/nightly
Browse files Browse the repository at this point in the history
V3.5.8 - Fix Download TikTok
  • Loading branch information
davidteather authored Oct 26, 2020
2 parents 36d24bf + 2cb655d commit 14e0f2d
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 39 deletions.
Binary file modified TikTokApi/__pycache__/browser.cpython-38.pyc
Binary file not shown.
Binary file modified TikTokApi/__pycache__/tiktok.cpython-38.pyc
Binary file not shown.
5 changes: 4 additions & 1 deletion TikTokApi/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def __init__(
debug=False,
newParams=False,
executablePath=None,
custom_did=None,
):
self.url = url
self.debug = debug
Expand All @@ -39,6 +40,7 @@ def __init__(
self.referrer = "https://www.tiktok.com/"
self.language = language
self.executablePath = executablePath
self.did = custom_did

self.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36"
self.args = [
Expand Down Expand Up @@ -165,7 +167,8 @@ async def start(self):
for i in range(16)
)

self.did = str(random.randint(10000, 999999999))
if self.did == None:
self.did = str(random.randint(10000, 999999999))

await self.page.evaluate("() => { " + get_acrawler() + " }")
self.signature = await self.page.evaluate(
Expand Down
112 changes: 80 additions & 32 deletions TikTokApi/tiktok.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,17 @@ def getBytes(self, b, **kwargs) -> bytes:
r = requests.get(
url,
headers={
"method": "GET",
"accept-encoding": "gzip, deflate, br",
"referer": b.referrer,
"user-agent": b.userAgent,
"Accept": "*/*",
"Accept-Encoding": "identity;q=1, *;q=0",
"Accept-Language": "en-US;en;q=0.9",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"cookie": "tt_webid_v2=" + b.did,
"Host": url.split("/")[2],
"Pragma": "no-cache",
"Range": "bytes=0-",
"Referer": "https://www.tiktok.com/",
"User-Agent": b.userAgent
},
proxies=self.__format_proxy(proxy),
)
Expand Down Expand Up @@ -762,7 +769,7 @@ def getHashtagDetails(self, hashtag, **kwargs) -> dict:
b = browser(api_url, proxy=proxy, executablePath=self.executablePath)
return self.getData(b, proxy=proxy)

def getRecommendedTikToksByVideoID(self, id, **kwargs) -> dict:
def getRecommendedTikToksByVideoID(self, id, count=30, **kwargs) -> dict:
"""Returns a dictionary listing reccomended TikToks for a specific TikTok video.
:param id: The id of the video to get suggestions for.
Expand All @@ -779,22 +786,53 @@ def getRecommendedTikToksByVideoID(self, id, **kwargs) -> dict:
maxCount,
offset,
) = self.__process_kwargs__(kwargs)
query = {
"count": 24,
"id": id,
"type": 0,
"secUid": "",
"maxCursor": maxCursor,
"minCursor": minCursor,
"shareUid": "",
"recType": 3,
"language": language,
}
api_url = "{}share/item/list?{}&{}".format(
BASE_URL, self.__add_new_params__(), urlencode(query)
)
b = browser(api_url, proxy=proxy, executablePath=self.executablePath)
return self.getData(b, proxy=proxy)["body"]

response = []
first = True

while len(response) < count:
if count < maxCount:
realCount = count
else:
realCount = maxCount

query = {
"count": realCount,
"id": 1,
"secUid": "",
"maxCursor": maxCursor,
"minCursor": minCursor,
"sourceType": 12,
"appId": 1233,
"region": region,
"priority_region": region,
"language": language,
}
api_url = "{}api/recommend/item_list/?{}&{}".format(
BASE_URL, self.__add_new_params__(), urlencode(query)
)
b = browser(
api_url,
language=language,
proxy=proxy,
executablePath=self.executablePath,
)
res = self.getData(b, proxy=proxy)

for t in res.get("items", []):
response.append(t)

if not res["hasMore"] and not first:
if self.debug:
print("TikTok isn't sending more TikToks beyond this point.")
return response[:count]

realCount = count - len(response)
maxCursor = res["maxCursor"]

first = False

return response[:count]

def getTikTokById(self, id, **kwargs) -> dict:
"""Returns a dictionary of a specific TikTok.
Expand All @@ -813,14 +851,15 @@ def getTikTokById(self, id, **kwargs) -> dict:
maxCount,
offset,
) = self.__process_kwargs__(kwargs)
did = kwargs.get("custom_did", None)
query = {
"itemId": id,
"language": language,
}
api_url = "{}api/item/detail/?{}&{}".format(
BASE_URL, self.__add_new_params__(), urlencode(query)
)
b = browser(api_url, proxy=proxy, executablePath=self.executablePath)
b = browser(api_url, proxy=proxy, executablePath=self.executablePath, custom_did=did)
return self.getData(b, proxy=proxy)

def getTikTokByUrl(self, url, **kwargs) -> dict:
Expand All @@ -840,6 +879,7 @@ def getTikTokByUrl(self, url, **kwargs) -> dict:
maxCount,
offset,
) = self.__process_kwargs__(kwargs)
custom_did = kwargs.get("custom_did", None)
if "@" in url and "/video/" in url:
post_id = url.split("/video/")[1].split("?")[0]
else:
Expand All @@ -848,7 +888,7 @@ def getTikTokByUrl(self, url, **kwargs) -> dict:
"https://www.tiktok.com/@therock/video/6829267836783971589"
)

return self.getTikTokById(post_id, language=language, proxy=proxy)
return self.getTikTokById(post_id, language=language, proxy=proxy, custom_did=custom_did)

def discoverHashtags(self, **kwargs) -> dict:
"""Discover page, consists challenges (hashtags)
Expand Down Expand Up @@ -1168,7 +1208,7 @@ def get_Video_By_TikTok(self, data, **kwargs) -> bytes:
try:
api_url = data["itemInfos"]["video"]["urls"][0]
except Exception:
api_url = data["itemInfo"]["itemStruct"]["video"]["downloadAddr"]
api_url = data["itemInfo"]["itemStruct"]["video"]["playAddr"]
return self.get_Video_By_DownloadURL(api_url, proxy=proxy)

def get_Video_By_DownloadURL(self, download_url, **kwargs) -> bytes:
Expand All @@ -1190,16 +1230,24 @@ def get_Video_By_DownloadURL(self, download_url, **kwargs) -> bytes:
return self.getBytes(b, proxy=proxy)

def get_Video_By_Url(
self, video_url, return_bytes=0, chromedriver_path=None
self, video_url, **kwargs
) -> bytes:
"""(DEPRECRATED)
Gets the source url of a given url for a tiktok
(
region,
language,
proxy,
minCursor,
maxCursor,
maxCount,
offset,
) = self.__process_kwargs__(kwargs)
did = str(random.randint(10000, 999999999))

tiktok_schema = self.getTikTokByUrl(video_url, custom_did=did)
download_url = tiktok_schema['itemInfo']['itemStruct']['video']['downloadAddr']

video_url - the url of the video
return_bytes - 0 is just the url, 1 is the actual video bytes
chromedriver_path - path to your chrome driver executable
"""
raise Exception("Deprecated. Other Methods Work Better.")
b = browser(download_url, proxy=proxy, custom_did=did)
return self.getBytes(b, proxy=proxy)

def get_Video_No_Watermark(self, video_url, return_bytes=0, **kwargs) -> bytes:
"""Gets the video with no watermark
Expand Down
5 changes: 0 additions & 5 deletions examples/downloadTikTok.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
# Starts TikTokApi
api = TikTokApi()

# Below is if you have a DIRECT tiktok url
tiktokData = api.get_Video_By_Url(
"https://www.tiktok.com/@ceciliaannborne/video/6817602864228207878", return_bytes=1
)

# Below is used if you have the download url from the tiktok object, but maybe not the full object
tiktokData = api.get_Video_By_DownloadURL(
api.trending(count=1)[0]["video"]["downloadAddr"]
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
setuptools.setup(
name="TikTokApi",
packages=["TikTokApi"],
version="3.5.7",
version="3.5.8",
license="MIT",
description="The Unofficial TikTok API Wrapper in Python 3.",
author="David Teather",
Expand Down

0 comments on commit 14e0f2d

Please sign in to comment.