Giter VIP home page Giter VIP logo

aiotiktok's Introduction

being of stupid developer

aiotiktok's People

Contributors

fast0n avatar sheldygg avatar uiucanh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

aiotiktok's Issues

client.get_video_data returns None

Issue: client.get_video_data returns None

Reproduce:

import asyncio

from aiotiktok.client import TikTokClient


async def main():
    client = TikTokClient()

    await client.get_video_data(video_id="7355983017472560416")

    await client.close()


print(asyncio.run(main()))

Result: None

something died ):

for aweme in data["aweme_list"]:
^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

what's the exact url?

I try both of these

https://www.tiktok.com/@sooshimango

https://www.tiktok.com/@sooshimango/video/7228919985777757442?lang=en

import asyncio
from aiotiktok import Client

tiktok = Client()

async def main():
    data = await tiktok.get_data(url="https://www.tiktok.com/@sooshimango/video/7228919985777757442?lang=en")
    print(data)
    
asyncio.run(main())

Traceback (most recent call last):
File "test.py", line 10, in
asyncio.run(main())
File "/Users/johndpope/opt/miniconda3/envs/spleeter/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/Users/johndpope/opt/miniconda3/envs/spleeter/lib/python3.7/asyncio/base_events.py", line 587, in run_until_complete
return future.result()
File "test.py", line 7, in main
data = await tiktok.get_data(url="https://www.tiktok.com/@sooshimango/video/7228919985777757442?lang=en")
File "/Users/johndpope/Documents/gitWorkspace/aiotiktok/aiotiktok/client.py", line 82, in get_data
video_id = await self.get_video_id(url)
File "/Users/johndpope/Documents/gitWorkspace/aiotiktok/aiotiktok/client.py", line 34, in get_video_id
if original_url == self.tiktok_url or "video" not in original_url:
UnboundLocalError: local variable 'original_url' referenced before assignment

Can't get data from photo slideshows

async def main():
    try:
        url = "https://www.tiktok.com/@unionhl2/photo/7336171154517822725"
        video_data = await client.video_data(url=url)
        print("Video data:", video_data)
    except Exception as e:
        print(f"An error occurred: {e}")

Output:
An error occurred: URLUnavailable, check the link

Feature request - feeds by username

Screenshot 2023-05-07 at 1 00 00 pm

I will help if I can adjust this -
here in the picture - this is app I bought - 4k tokkit - it's good - but no command line.
there's 636 videos in their feed.

UPDATE - I found this logic
https://github.com/acomarcho/tiktok-api
https://github.com/dfreelon/pyktok
https://github.com/ART-Open-Source/M-API/blob/c1550880b4097300ee22a24ab9c850542a674230/src/tiktok/tiktok_tools.py#L1

seems like people are stuck on pagination.
dfreelon/pyktok#21

https://github.com/acomarcho/tiktok-api/blob/main/services/tiktok.js

super fragile -

  const res = await superagent.get(`https://www.tiktok.com/@${username}`);
    const htmlText = res.text;
    ``;
    // Get AppContext
    const pattern =
      /<script id="SIGI_STATE" type="application\/json">(.*?)<\/script>/s;
    const match = htmlText.match(pattern);

    if (match) {
      const jsonData = JSON.parse(match[1]);

      // Posts
      const itemModule = jsonData.ItemModule;

I normally use BeautifulSoup for this stuff.

import requests
import time
import csv
import re
from bs4 import BeautifulSoup
import json
import os



i have this response data from tiktok api - is it simple to download mp4? doesn't seem obvious.

  "comment_count" = 0;
                "cover_image_url" = "https://image-va.tiktokv.com/tos-maliva-p-0068/db6ebfba88714460a6fe451b23ed00fb~tplv-tiktokx-360p.image?policy=eyJ2bSI6MywidWlkIjoiNjU1Nzk0NjAxNzE2OTY1Mzc2NSJ9&x-orig-authkey=953b87ea9b474969e4eab20d5c7fa858d23f02a8&x-orig-expires=1684501200&x-orig-sign=Vo6rFKDZ5kgLRqNwqBjgG8RWszI%3D&s=TIKTOK_FOR_DEVELOPER&se=false&sh=&sc=feed_cover&l=20230518135132CE8A42F44F6E065AB657";
                "create_time" = 1536870540;
                duration = 17;
                "embed_html" = "<blockquote class=\"tiktok-embed\" cite=\"https://www.tiktok.com/@MS4wLjABAAAAYZzSo-9gjsngkw8WopqpFu65NTyVUDWy9K5-8P3azIHvTJjyAFRL0-woJnU3qgrZ/video/6600808708635102470?utm_campaign=tt4d_open_api&utm_source=aw9uhhaa07hhuj75\" data-video-id=\"6600808708635102470\" style=\"max-width: 605px;min-width: 325px;\" > <section> <a target=\"_blank\" title=\"@_l\U00f8veisl\U00f8ve_\" href=\"https://www.tiktok.com/@MS4wLjABAAAAYZzSo-9gjsngkw8WopqpFu65NTyVUDWy9K5-8P3azIHvTJjyAFRL0-woJnU3qgrZ\">@_l\U00f8veisl\U00f8ve_</a>  <a target=\"_blank\" title=\"\U266c original sound - _l\U00f8veisl\U00f8ve_ - \Ud83c\Udff3\Ufe0f\Ud83c\Udf08gay gang \Ud83c\Udff3\Ufe0f\Ud83c\Udf08\" href=\"https://www.tiktok.com/music/6600808751219870470-original+sound+-+_l%C3%B8veisl%C3%B8ve_\">\U266c original sound - _l\U00f8veisl\U00f8ve_ - \Ud83c\Udff3\Ufe0f\Ud83c\Udf08gay gang \Ud83c\Udff3\Ufe0f\Ud83c\Udf08</a> </section> </blockquote> <script async src=\"https://www.tiktok.com/embed.js\"></script>";
                "embed_link" = "https://www.tiktok.com/static/profile-video?id=6600808708635102470&hide_author=1&utm_campaign=tt4d_open_api&utm_source=aw9uhhaa07hhuj75";
                height = 672;
                id = 6600808708635102470;
                "like_count" = 9;
                "share_count" = 0;
                "share_url" = "https://www.tiktok.com/@_l\U00f8veisl\U00f8ve_/video/6600808708635102470?utm_campaign=tt4d_open_api&utm_source=aw9uhhaa07hhuj75";
                title = "";
                "video_description" = "";
                "view_count" = 30;
                width = 960;
            },

405: Method Not Allowed

signature_data: b'405: Method Not Allowed'
Traceback (most recent call last):
File "/Users/johndpope/Desktop/test.py", line 11, in
asyncio.run(main())
File "/Users/johndpope/miniconda3/envs/py310/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Users/johndpope/miniconda3/envs/py310/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
return future.result()
File "/Users/johndpope/Desktop/test.py", line 8, in main
await tiktok.user_feed_sig("playboicarti")
File "/Users/johndpope/miniconda3/envs/py310/lib/python3.10/site-packages/aiotiktok/client.py", line 168, in user_feed_sig
user_videos = (await self._get_user_feed_private(username))[:count]
File "/Users/johndpope/miniconda3/envs/py310/lib/python3.10/site-packages/aiotiktok/client.py", line 136, in _get_user_feed_private
"x-tt-params": signature_data.get("x-tt-params"),
AttributeError: 'bytes' object has no attribute 'get'

import asyncio
from aiotiktok import Client

tiktok = Client(signature_url="http://111.111.111.111:8002")
async def main():
    await tiktok.user_feed_sig("playboicarti")
asyncio.run(main())

I think it's a CORS issue - do I need SSL?

expanding code by openapi.json

I used some sample code by chatgpt to scaffold these calls

Screenshot 2023-06-01 at 12 26 21 pm

may not be so helpful - but if the calls are all matched up - would be a good feature set.
Have to do some manually mapping - (people could contribute via PR)
eg. for number 1)
/public/followers ->
/aweme/v1/user/follower/list/
https://github.com/kingking888/app-crawler/blob/5a8211671efc86d01f72c9bfdb4543aff135c5d7/app/event.py#L16


        'login': (url_api, 'passport/user/login/'),
        'user_info': (url_api16, '/aweme/v1/user/'),

        'search_human': (url_api16, '/aweme/v1/discover/search/'),
        'search_ht':  (url_api16, '/aweme/v1/challenge/search/'),

        'followers_list':  (url_api, 'aweme/v1/user/follower/list/'),
        'followings_list':  (url_api16, 'aweme/v1/user/following/list/'),

        'like':  (url_api16, '/aweme/v1/commit/item/digg/'),

        'follow': (url_api16, '/aweme/v1/commit/follow/user/'),
        'posts': (url_api16, '/aweme/v1/aweme/post/'),

        'comments_list':  (url_api16, '/aweme/v1/comment/list')

UPDATE

private static final ArrayList<String> f68802f = n.d("/service/1/update_token/", "/aweme/v1/aweme/detail/", "/aweme/v1/user/", "/aweme/v1/abtest/param/", "/aweme/v1/commerce/settings", "/aweme/v1/feed/", "/aweme/v1/settings/", "/aweme/v1/story/", "/aweme/v1/user/settings/", "/aweme/v1/im/cloud/token/", "/aweme/v1/upload/contacts/", "/aweme/v1/aweme/post/", "/aweme/v1/user/", "/aweme/v1/commit/follow/user/", "/aweme/v1/multi/aweme/detail/", "/aweme/v1/comment/publish/", "/aweme/v1/general/search/", "/passport/user/logout/", "/aweme/v1/commit/item/digg/", "/user/mobile/reset_password/", "/passport/auth/login/", "/aweme/v1/create/aweme/", "/aweme/v1/recommend/user/", "/aweme/v2/comment/list/", "/passport/mobile/login/", "/aweme/v1/user/follower/list/", "/aweme/v1/notice/count/", "/aweme/v1/friend/feed/", "/aweme/v1/aweme/stats/", "/aweme/v1/hot/search/list/", "/aweme/v1/recommend/challenge/");

class MyAPIClient(OpenAPIClient):
    async def public.check(self, **kwargs):
    url = self.build_url("/public/check")
    return await self.request("get", url, **kwargs)

async def public.followersList(self, **kwargs):
    url = self.build_url("/public/followers")
    return await self.request("get", url, **kwargs)


async def public.posts(self, **kwargs):
    url = self.build_url("/public/posts")
    return await self.request("get", url, **kwargs)


async def public.likes(self, **kwargs):
    url = self.build_url("/public/likes")
    return await self.request("get", url, **kwargs)


async def public.followingList(self, **kwargs):
    url = self.build_url("/public/following")
    return await self.request("get", url, **kwargs)


async def public.explore(self, **kwargs):
    url = self.build_url("/public/explore")
    return await self.request("get", url, **kwargs)


async def public.video(self, **kwargs):
    url = self.build_url("/public/video")
    return await self.request("get", url, **kwargs)


async def public.hashtag(self, **kwargs):
    url = self.build_url("/public/hashtag")
    return await self.request("get", url, **kwargs)


async def public.music(self, **kwargs):
    url = self.build_url("/public/music")
    return await self.request("get", url, **kwargs)


async def public.musicInfo(self, **kwargs):
    url = self.build_url("/public/music/info")
    return await self.request("get", url, **kwargs)


async def public.discover(self, **kwargs):
    url = self.build_url("/public/discover/{category}")
    return await self.request("get", url, **kwargs)


async def public.discoverKeyword(self, **kwargs):
    url = self.build_url("/public/discover/keyword")
    return await self.request("get", url, **kwargs)


async def public.search(self, **kwargs):
    url = self.build_url("/public/search/{category}")
    return await self.request("get", url, **kwargs)


async def user.info(self, **kwargs):
    url = self.build_url("/user/info")
    return await self.request("get", url, **kwargs)


async def user.edit(self, **kwargs):
    url = self.build_url("/user/edit/{field}")
    return await self.request("post", url, **kwargs)


async def user.notifications(self, **kwargs):
    url = self.build_url("/user/notifications")
    return await self.request("get", url, **kwargs)


async def user.analytics(self, **kwargs):
    url = self.build_url("/creator/analytics/{type}")
    return await self.request("get", url, **kwargs)


async def user.verify(self, **kwargs):
    url = self.build_url("/user/session/check")
    return await self.request("get", url, **kwargs)


async def user.following(self, **kwargs):
    url = self.build_url("/user/following")
    return await self.request("get", url, **kwargs)


async def user.follow(self, **kwargs):
    url = self.build_url("/user/follow")
    return await self.request("post", url, **kwargs)


async def user.unfollow(self, **kwargs):
    url = self.build_url("/user/unfollow")
    return await self.request("post", url, **kwargs)


async def user.posts.feed(self, **kwargs):
    url = self.build_url("/user/feed")
    return await self.request("get", url, **kwargs)


async def user.posts.likes(self, **kwargs):
    url = self.build_url("/user/likes")
    return await self.request("get", url, **kwargs)


async def user.posts.explore(self, **kwargs):
    url = self.build_url("/user/explore")
    return await self.request("get", url, **kwargs)


async def user.posts.video(self, **kwargs):
    url = self.build_url("/user/video")
    return await self.request("get", url, **kwargs)


async def user.posts.like(self, **kwargs):
    url = self.build_url("/user/like")
    return await self.request("post", url, **kwargs)


async def user.posts.unlike(self, **kwargs):
    url = self.build_url("/user/unlike")
    return await self.request("post", url, **kwargs)


async def user.posts.comments.list(self, **kwargs):
    url = self.build_url("/comment/list")
    return await self.request("get", url, **kwargs)


async def user.posts.comments.replies(self, **kwargs):
    url = self.build_url("/comment/reply/list")
    return await self.request("get", url, **kwargs)


async def user.posts.comments.post(self, **kwargs):
    url = self.build_url("/user/comment")
    return await self.request("post", url, **kwargs)


async def user.posts.comments.like(self, **kwargs):
    url = self.build_url("/user/comment/like")
    return await self.request("post", url, **kwargs)


async def user.posts.comments.unlike(self, **kwargs):
    url = self.build_url("/user/comment/unlike")
    return await self.request("post", url, **kwargs)


async def user.posts.comments.delete(self, **kwargs):
    url = self.build_url("/user/comment/delete")
    return await self.request("post", url, **kwargs)


async def user.conversations(self, **kwargs):
    url = self.build_url("/user/conversations")
    return await self.request("get", url, **kwargs)


async def user.messages(self, **kwargs):
    url = self.build_url("/user/messages")
    return await self.request("get", url, **kwargs)


async def user.sendMessage(self, **kwargs):
    url = self.build_url("/user/message/send")
    return await self.request("post", url, **kwargs)


async def user.live.permissions(self, **kwargs):
    url = self.build_url("/user/live/info")
    return await self.request("get", url, **kwargs)


async def user.live.start(self, **kwargs):
    url = self.build_url("/user/live/start")
    return await self.request("post", url, **kwargs)


async def user.live.stop(self, **kwargs):
    url = self.build_url("/user/live/stop")
    return await self.request("post", url, **kwargs)


async def user.live.info(self, **kwargs):
    url = self.build_url("/user/live/check")
    return await self.request("get", url, **kwargs)


async def user.live.recommend(self, **kwargs):
    url = self.build_url("/user/live/recommend")
    return await self.request("get", url, **kwargs)


async def user.live.stats(self, **kwargs):
    url = self.build_url("/user/live/stats")
    return await self.request("get", url, **kwargs)


async def user.live.chat(self, **kwargs):
    url = self.build_url("/user/live/chat")
    return await self.request("get", url, **kwargs)


async def user.live.sendChat(self, **kwargs):
    url = self.build_url("/user/live/chat/send")
    return await self.request("post", url, **kwargs)


async def user.live.topics(self, **kwargs):
    url = self.build_url("/user/live/topics")
    return await self.request("get", url, **kwargs)


async def user.live.transactionHistory(self, **kwargs):
    url = self.build_url("/user/wallet/transactions")
    return await self.request("get", url, **kwargs)


async def key(self, **kwargs):
    url = self.build_url("/key/info")
    return await self.request("get", url, **kwargs)

https://gist.github.com/wweevv-johndpope/04ab609277ecffb4335de719acbba0ac

MsgSpec / struct -> dict

is there an easy way to turn the video_data into a dict / json response?

I want to return json in web response.

these approaches using chatgpt didn't help.

from fastapi.encoders import jsonable_encoder

data = await tiktok.video_data(video_id=id)
return json_response(jsonable_encoder([data]))

# Assuming you have a struct model called `YourStructModel`
your_struct_model = YourStructModel(...)  # Create an instance of your struct model

# Serialize the struct model into bytes using msgspec
serialized_data = msgspec.dumps(your_struct_model)

# Decode the bytes into a JSON string
json_string = serialized_data.decode()

# Convert the JSON string into a Python dictionary
json_dict = json.loads(json_string)

# Return the JSON dictionary as the response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.