Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'TikTokApi' object has no attribute 'browser' #62

Closed
LikeADemonicMind opened this issue Aug 19, 2024 · 10 comments
Closed

'TikTokApi' object has no attribute 'browser' #62

LikeADemonicMind opened this issue Aug 19, 2024 · 10 comments

Comments

@LikeADemonicMind
Copy link

Hi! I hope you're doing well.

I've seen that you updated PykTok on July and that save_tiktok_multi_page worked again, so I wanted to try it out!
Unfortunately, I've got an error while trying to launch my code:
'TikTokApi' object has no attribute 'browser'

Here's my code:
import nest_asyncio # needed because of the "asyncio.run() cannot be called from a running event loop pyktok" error nest_asyncio.apply() import pyktok as pyk pyk.save_tiktok_multi_page('yourgirlangeel', save_video=False,metadata_fn='tiktok.csv')

Here's the full cell output:

NotImplementedError Traceback (most recent call last)
File ~\anaconda3\envs\chatbot\Lib\site-packages\pyktok\pyktok.py:340, in get_video_urls(tt_ent, ent_type, video_ct, headless)
339 async with TikTokApi() as api:
--> 340 await api.create_sessions(headless=headless,
341 ms_tokens=[ms_token],
342 num_sessions=1,
343 sleep_after=3,
344 context_options=context_dict)
345 if ent_type == 'user':

File ~\anaconda3\envs\chatbot\Lib\site-packages\TikTokApi\tiktok.py:245, in TikTokApi.create_sessions(self, num_sessions, headless, ms_tokens, proxies, sleep_after, starting_url, context_options, override_browser_args, cookies, suppress_resource_load_types, browser, executable_path)
218 """
219 Create sessions for use within the TikTokApi class.
220
(...)
243 await api.create_sessions(num_sessions=5, ms_tokens=['msToken1', 'msToken2'])
244 """
--> 245 self.playwright = await async_playwright().start()
246 if browser == "chromium":

File ~\anaconda3\envs\chatbot\Lib\site-packages\playwright\async_api_context_manager.py:51, in PlaywrightContextManager.start(self)
50 async def start(self) -> AsyncPlaywright:
---> 51 return await self.aenter()

File ~\anaconda3\envs\chatbot\Lib\site-packages\playwright\async_api_context_manager.py:46, in PlaywrightContextManager.aenter(self)
45 playwright_future.cancel()
---> 46 playwright = AsyncPlaywright(next(iter(done)).result())
47 playwright.stop = self.aexit # type: ignore

File ~\anaconda3\envs\chatbot\Lib\asyncio\futures.py:203, in Future.result(self)
202 if self._exception is not None:
--> 203 raise self._exception.with_traceback(self._exception_tb)
204 return self._result

File ~\anaconda3\envs\chatbot\Lib\site-packages\playwright_impl_transport.py:120, in PipeTransport.connect(self)
119 executable_path, entrypoint_path = compute_driver_executable()
--> 120 self._proc = await asyncio.create_subprocess_exec(
121 executable_path,
122 entrypoint_path,
123 "run-driver",
124 stdin=asyncio.subprocess.PIPE,
125 stdout=asyncio.subprocess.PIPE,
126 stderr=_get_stderr_fileno(),
127 limit=32768,
128 env=env,
129 startupinfo=startupinfo,
130 )
131 except Exception as exc:

File ~\anaconda3\envs\chatbot\Lib\asyncio\subprocess.py:223, in create_subprocess_exec(program, stdin, stdout, stderr, limit, *args, **kwds)
221 protocol_factory = lambda: SubprocessStreamProtocol(limit=limit,
222 loop=loop)
--> 223 transport, protocol = await loop.subprocess_exec(
224 protocol_factory,
225 program, *args,
226 stdin=stdin, stdout=stdout,
227 stderr=stderr, **kwds)
228 return Process(transport, protocol, loop)

File ~\anaconda3\envs\chatbot\Lib\asyncio\base_events.py:1694, in BaseEventLoop.subprocess_exec(self, protocol_factory, program, stdin, stdout, stderr, universal_newlines, shell, bufsize, encoding, errors, text, *args, **kwargs)
1693 self._log_subprocess(debug_log, stdin, stdout, stderr)
-> 1694 transport = await self._make_subprocess_transport(
1695 protocol, popen_args, False, stdin, stdout, stderr,
1696 bufsize, **kwargs)
1697 if self._debug and debug_log is not None:

File ~\anaconda3\envs\chatbot\Lib\asyncio\base_events.py:502, in BaseEventLoop._make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra, **kwargs)
501 """Create subprocess transport."""
--> 502 raise NotImplementedError

NotImplementedError:

During handling of the above exception, another exception occurred:

AttributeError Traceback (most recent call last)
Cell In[10], line 1
----> 1 pyk.save_tiktok_multi_page('tiktok', save_video=False,metadata_fn='tiktok.csv')

File ~\anaconda3\envs\chatbot\Lib\site-packages\pyktok\pyktok.py:394, in save_tiktok_multi_page(tt_ent, ent_type, video_ct, headless, save_video, metadata_fn, sleep, browser_name)
386 def save_tiktok_multi_page(tt_ent,
387 ent_type="user",
388 video_ct=30,
(...)
392 sleep=4,
393 browser_name=None):
--> 394 video_urls = asyncio.run(get_video_urls(tt_ent,
395 ent_type,
396 video_ct,
397 headless))
398 save_tiktok_multi_urls(video_urls,
399 save_video,
400 metadata_fn,
401 sleep,
402 browser_name)

File ~\anaconda3\envs\chatbot\Lib\site-packages\nest_asyncio.py:30, in _patch_asyncio..run(main, debug)
28 task = asyncio.ensure_future(main)
29 try:
---> 30 return loop.run_until_complete(task)
31 finally:
32 if not task.done():

File ~\anaconda3\envs\chatbot\Lib\site-packages\nest_asyncio.py:98, in _patch_loop..run_until_complete(self, future)
95 if not f.done():
96 raise RuntimeError(
97 'Event loop stopped before Future completed.')
---> 98 return f.result()

File ~\anaconda3\envs\chatbot\Lib\asyncio\futures.py:203, in Future.result(self)
201 self.__log_traceback = False
202 if self._exception is not None:
--> 203 raise self._exception.with_traceback(self._exception_tb)
204 return self._result

File ~\anaconda3\envs\chatbot\Lib\asyncio\tasks.py:277, in Task.__step(failed resolving arguments)
273 try:
274 if exc is None:
275 # We use the send method directly, because coroutines
276 # don't have __iter__ and __next__ methods.
--> 277 result = coro.send(None)
278 else:
279 result = coro.throw(exc)

File ~\anaconda3\envs\chatbot\Lib\site-packages\pyktok\pyktok.py:339, in get_video_urls(tt_ent, ent_type, video_ct, headless)
336 url_p2 = "/video/"
337 tt_list = []
--> 339 async with TikTokApi() as api:
340 await api.create_sessions(headless=headless,
341 ms_tokens=[ms_token],
342 num_sessions=1,
343 sleep_after=3,
344 context_options=context_dict)
345 if ent_type == 'user':

File ~\anaconda3\envs\chatbot\Lib\site-packages\TikTokApi\tiktok.py:493, in TikTokApi.aexit(self, exc_type, exc, tb)
491 async def aexit(self, exc_type, exc, tb):
492 await self.close_sessions()
--> 493 await self.stop_playwright()

File ~\anaconda3\envs\chatbot\Lib\site-packages\TikTokApi\tiktok.py:480, in TikTokApi.stop_playwright(self)
478 async def stop_playwright(self):
479 """Stop the playwright browser"""
--> 480 await self.browser.close()
481 await self.playwright.stop()

AttributeError: 'TikTokApi' object has no attribute 'browser'

I've already tried the solution here #61 but it doesn't work for me...
Here are the versions of all of my packages:
pyktok : 0.0.29
beautifulsoup : 4.12.3
browser-cookie3 : 0.19.1
numpy : 1.26.4
pandas : 2.2.0
requests : 2.32.3
tiktokapi : 6.4.0
python version : 3.11.7

Thanks a lot for your work!

@dfreelon
Copy link
Owner

Hello. Can you please state the IDE and OS you are using? Thanks.

@LikeADemonicMind
Copy link
Author

I'm working on Jupyter Lab and on Windows 10 Pro.

@dfreelon
Copy link
Owner

I just tested your code and it worked fine for me. You may need to try it out in a console or PowerShell window. You shouldn't need to run import nest_asyncio, it should work fine with the following two statements only.

@LikeADemonicMind
Copy link
Author

You're right, I don't have this error anymore but get this one instead :
TikTokApi.exceptions.EmptyResponseException: None -> TikTok returned an empty response

Can you give me the version of the TikTokApi you're using please?

@dfreelon
Copy link
Owner

That is an upstream error, which means the code did what it was supposed to but TikTok basically blocked you. Here are some solutions to try:

  • Try from a different network (e.g. home vs. work)
  • Use a VPN if you have access to one
  • Try with the headless parameter set to False
  • Try to download from a hashtag or specific video instead of a user just to see if you can get a valid result

@dfreelon
Copy link
Owner

Also I'm using TikTokApi 6.3.0

@LikeADemonicMind
Copy link
Author

Thanks for your advices!
I've downgraded TikTokApi.
It works for hashtags and for some users but not all of them... I don't know why but I'll try to figure it out.

@dfreelon
Copy link
Owner

Good luck!

@LikeADemonicMind
Copy link
Author

Thanks!
So, I realized that it works for european creators (I'm in Europe) but not others... maybe a geographic limitation!

@dfreelon
Copy link
Owner

Interesting... you could potentially use a VPN to get around that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants