davidteather / TikTok-Api

The Unofficial TikTok API Wrapper In Python
https://davidteather.github.io/TikTok-Api
MIT License
4.58k stars 933 forks source link

[BUG] - EmptyResponseException: None -> TikTok returned an empty response #1090

Open ketanmalempati opened 7 months ago

ketanmalempati commented 7 months ago

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 image image And sometimes it just throws the error without any output image

Thank you

Samael27 commented 7 months ago

I have the same error on mac os (if it help)

JonathanReiss15 commented 7 months ago

Same here

eterice commented 7 months ago

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?

hantconny commented 7 months ago

compared with the request in chrome, a param _signature is missed

binaryplatitude commented 7 months ago

Same issue here

Manuel3003 commented 7 months ago

Same issue. Tried different setup, same IP. Working there.

jimmychuang95 commented 7 months ago

@davidteather same here…

doanbh commented 7 months ago

same issue

KillaMeep commented 7 months ago

Gotta bump this. I have the same issue as well. Running within a venv on python 3.11.4 and still getting issues.

rahdor commented 7 months ago

having the same issue while running in a python notebook

eliich commented 7 months ago

compared with the request in chrome, a param _signature is missed

Yes that seems to be the problem.

NateGroth commented 7 months ago

Yup, runs fine every once in a while. Running the exact same code a second time ends up throwing an error.

hulk10425 commented 7 months ago

same issue here

eterice commented 7 months ago

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!

lynyanny commented 7 months ago

same here

sherlock440 commented 7 months ago

@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?

joseantgv commented 7 months ago

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'
kulig1985 commented 6 months ago

Same here.. 🤨

NateGroth commented 6 months ago

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

Ben3056 commented 6 months ago

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.

gabrielrosendo commented 6 months ago

@Ben3056 That fixed the issue, but it's opening TikTok on my browser now every time I run the code. Any ideas why?

hantconny commented 6 months ago

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

hantconny commented 6 months ago

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.

yangsu10yen commented 6 months ago

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()
jpratt9 commented 5 months ago

@yangsu10yen could you please provide more context for your solution? Where does this "cookie" object/class come from in code?

yangsu10yen commented 5 months ago

@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
jpratt9 commented 5 months ago

@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?

yangsu10yen commented 5 months ago

@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.

unlucky-kit commented 4 months ago

@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.

Kkordik commented 3 months ago

@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

MorgusLethe commented 1 month ago

@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

Confirmed working today.

For anyone starting out with this project for the first time and trying to get the first examples to just work, here's what I did.

I used Docker. The Dockerfile in the root of this project is not working anymore, because the image is outdated and uses Python 3.8, but this project requires 3.9. I changed "focal" to "jammy" and rebuilt the image.

Run a container and change the /usr/local/lib/python3.10/dist-packages/TikTokApi/tiktok.py file. You can change it according to the link in the quoted comment, but I was getting some errors, so I just added these two lines to the top of the file: executable_path="/opt/google/chrome/google-chrome" and browser="chromium" but you might not need the second one.

Install chrome according to the instructions in link.

Put your example file in the /TikTokApi folder and enter your ms_token, and run it and it will work.

Thanks, everyone!

dmtrung14 commented 1 month ago

Is there a way to make this work with browser=firefox?

nathanuel0322 commented 1 month ago

@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

Confirmed working today.

For anyone starting out with this project for the first time and trying to get the first examples to just work, here's what I did.

I used Docker. The Dockerfile in the root of this project is not working anymore, because the image is outdated and uses Python 3.8, but this project requires 3.9. I changed "focal" to "jammy" and rebuilt the image.

Run a container and change the /usr/local/lib/python3.10/dist-packages/TikTokApi/tiktok.py file. You can change it according to the link in the quoted comment, but I was getting some errors, so I just added these two lines to the top of the file: executable_path="/opt/google/chrome/google-chrome" and browser="chromium" but you might not need the second one.

Install chrome according to the instructions in link.

Put your example file in the /TikTokApi folder and enter your ms_token, and run it and it will work.

Thanks, everyone!

You're goated, this worked! Thank you.

VuLemon commented 1 month ago

I checked the tiktok.py file and it seems remarkably different from the screenshots included here. Apparently the fixes have been integrated into the file, so we no longer have to manually change it ourselves.

That said, I still can not run the example code included in the manual solution. I think it has to do with me using a Mac and having a different path to Google Chrome's executable. If there's a fix for Mac users I would greatly appreciate it

@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

Confirmed working today.

For anyone starting out with this project for the first time and trying to get the first examples to just work, here's what I did.

I used Docker. The Dockerfile in the root of this project is not working anymore, because the image is outdated and uses Python 3.8, but this project requires 3.9. I changed "focal" to "jammy" and rebuilt the image.

Run a container and change the /usr/local/lib/python3.10/dist-packages/TikTokApi/tiktok.py file. You can change it according to the link in the quoted comment, but I was getting some errors, so I just added these two lines to the top of the file: executable_path="/opt/google/chrome/google-chrome" and browser="chromium" but you might not need the second one.

Install chrome according to the instructions in link.

Put your example file in the /TikTokApi folder and enter your ms_token, and run it and it will work.

Thanks, everyone!

PedroDaumas commented 3 weeks ago

If you are using docker, the Playwright version 1.37 has the correct chrome version that works. FROM mcr.microsoft.com/playwright/python:v1.37.0-jammy You'll still need to add the executable_path argument and point to "/ms-playwright/chromium-1076/chrome-linux/chrome"

async with TikTokApi() as api:
        await api.create_sessions(
            ms_tokens=[ms_token],
            num_sessions=1,
            sleep_after=3,
            executable_path="/ms-playwright/chromium-1076/chrome-linux/chrome",
        )