TikTok-Api
TikTok-Api copied to clipboard
[BUG] - EmptyResponseException: None -> TikTok returned an empty response
Hi,
I tried running the example code on the latest version and found this error empty response on all the examples.
It works sometimes and suddenly throws that error.
Any idea on how to fix this
And sometimes it just throws the error without any output
Thank you
I have the same error on mac os (if it help)
Same here
I encountered this problem as well. Why does it throw an error when I didn't add the parameter headless=False? Can I run the code without a browser popping up?
compared with the request in chrome, a param _signature is missed
Same issue here
Same issue. Tried different setup, same IP. Working there.
@davidteather same here…
same issue
Gotta bump this. I have the same issue as well. Running within a venv on python 3.11.4 and still getting issues.
having the same issue while running in a python notebook
compared with the request in chrome, a param _signature is missed
Yes that seems to be the problem.
Yup, runs fine every once in a while. Running the exact same code a second time ends up throwing an error.
same issue here
compared with the request in chrome, a param _signature is missed
Do you mean that we can sovle this problem by adding this param? where should I add this param? I'm new to python, thanks!
same here
@davidteather will it be possible to fix the issue? Or it is not widespread and only "lucky guys" like we in the topic have encountered it?
Same here.
Just installed and executed the user_example test:
python -m examples.user_example
2023-12-20 11:46:02,960 - TikTokApi.tiktok - ERROR - Got an unexpected status code: {'userInfo': {'user': {}, 'stats': {}, 'shareMeta': {}}}
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "D:\temp\TikTok-Api-6.2.0\examples\user_example.py", line 23, in <module>
asyncio.run(user_example())
File "C:\Program Files\Python311\Lib\asyncio\runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "D:\temp\TikTok-Api-6.2.0\examples\user_example.py", line 14, in user_example
user_data = await user.info()
^^^^^^^^^^^^^^^^^
File "D:\temp\TikTok-Api-6.2.0\TikTokApi\api\user.py", line 87, in info
self.__extract_from_data()
File "D:\temp\TikTok-Api-6.2.0\TikTokApi\api\user.py", line 204, in __extract_from_data
data["userInfo"]["user"]["id"],
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
KeyError: 'id'
Same here.. 🤨
I haven't looked into this issue of missing parameters for a while (kinda abandoned my project once this issue arose) but one possible solution could be to copy ALL headers/parameters and send those with a request. A brute force approach if you will
If you add headless=False into the create_sessions parameters like so:
await api.create_sessions(ms_tokens=[ms_token], num_sessions=1, sleep_after=3, headless=False)
Then it opens the browser briefly which is annoying but stops the empty response error from occurring.
@Ben3056 That fixed the issue, but it's opening TikTok on my browser now every time I run the code. Any ideas why?
take a different approach, using driver.get_log("performance") to fetch performance log, and then filter the response i want, normally, we should focus on api/post/item_list, it's json object, so it should be easy for python to parse that
compared with the request in chrome, a param _signature is missed
Do you mean that we can sovle this problem by adding this param? where should I add this param? I'm new to python, thanks!
I would not say that, beacuse the three parameters carried by url msToken,_signature,X-bogus are caculated by something depend on your matchine, I'm not very much in the tiktok's source code, google gives me the above conclusion.
Hi,
I have encountered the same problem and am investigating a solution. In the process, when creating the Playwright instance, I specified the 'executable_path' as the same browser that generated the cookie, and it responded successfully.
--- a/TikTokApi/tiktok.py
+++ b/TikTokApi/tiktok.py
@@ -212,6 +212,7 @@ class TikTokApi:
override_browser_args: list[dict] = None,
cookies: list[dict] = None,
suppress_resource_load_types: list[str] = None,
+ executable_path: str = None,
):
"""
Create sessions for use within the TikTokApi class.
@@ -230,6 +231,7 @@ class TikTokApi:
override_browser_args (list[dict]): A list of dictionaries containing arguments to pass to the browser.
cookies (list[dict]): A list of cookies to use for the sessions, you can get these from your cookies after visiting TikTok.
suppress_resource_load_types (list[str]): Types of resources to suppress playwright from loading, excluding more types will make playwright faster.. Types: document, stylesheet, image, media, font, script, textrack, xhr, fetch, eventsource, websocket, manifest, other.
+ executable_path (str): Path to a browser executable to run instead of the bundled one.
Example Usage:
.. code-block:: python
@@ -243,7 +245,8 @@ class TikTokApi:
override_browser_args = ["--headless=new"]
headless = False # managed by the arg
self.browser = await self.playwright.chromium.launch(
- headless=headless, args=override_browser_args, proxy=random_choice(proxies)
+ headless=headless, args=override_browser_args, proxy=random_choice(proxies),
+ executable_path=executable_path
)
api = TikTokApi(logging_level=logging.DEBUG)
try:
# `cookie` is extracted Chrome cookie
# `/opt/google/chrome/google-chrome` is Chrome executable path which generates Cookie
await api.create_sessions(cookies=[cookie.get('tiktok.com')], num_sessions=1, sleep_after=3, executable_path='/opt/google/chrome/google-chrome')
trends = [decamelize(t.as_dict) async for t in api.trending.videos(count=10)]
print(json.dumps(trends, ensure_ascii=False, indent=2))
finally:
await api.close_sessions()
await api.stop_playwright()
@yangsu10yen could you please provide more context for your solution? Where does this "cookie" object/class come from in code?
@jpratt9
The cookie
object comes from below code.
import os
import browsercookie
COOKIE = os.path.expanduser('~/.config/google-chrome/Default/Cookies')
cookie_jar = browsercookie.chrome([COOKIE])
cookies = [
{
'name': c.name,
'domain': c.domain,
'path': c.path,
'value': c.value
}
for c in cookie_jar if '.tiktok.com' in c.domain]
Upon further investigation of this issue, it was determined that the above code (using executable_path
) does not work on some versions of Google Chrome.
Specifically, we found the following behavior.
Version | Result |
---|---|
115.0.5790.170 | OK |
121.0.6167.57 | NG |
For this reason, I downloaded and installed an older version of Google Chrome with the following code
I then specified this Google Chrome executable path in executable_path
and verified that it works correctly.
$ wget https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_115.0.5790.170-1_amd64.deb -O google-chome.deb
$ sudo apt-get -y install `pwd`/google-chome.deb
@yangsu10yen thanks for clarifying, I think most of that makes sense to me. What I still don't understand is how the executable_path
variable is used in the code as you implemented it? It looks like you just added it as a parameter for create_sessions
then it's not used anywhere else?
@jpratt9
The executable_path
is passed as an argument to self.playwright.chromium.launch()
of the method create_sessions()
in this library (see my comment)
In the playwright used in this library, if a valid browser path is passed to executable_path
, it will be used.
@Ben3056 That fixed the issue, but it's opening TikTok on my browser now every time I run the code. Any ideas why?
Headless means the automation occurs without the browser's GUI appearing. When you choose the headless parameter to be false, it opens the browser. Quick note: headless automations are easier to detect, so TikTok probably cracked down on headless automations. So I think that's why the headless option does not work.
@yangsu10yen Your solution works, thanks!
I have created a guide on how to fix the error with the solution that proposed @yangsu10yen us. You can read and run it at google colab:
https://colab.research.google.com/drive/14FV3Ja3rmrubQ1FVLNhByTz1n_MPPlKA?usp=sharing