diff --git a/articles/research-api.html b/articles/research-api.html index 67c7fd4..7e31ebd 100644 --- a/articles/research-api.html +++ b/articles/research-api.html @@ -82,6 +82,25 @@ all comments of a video with tt_comments_api or tt_comments +
  • You can get +the videos a user has liked with +tt_user_liked_videos_api or tt_get_liked +
  • +
  • You can get +the videos a user has reposted with +tt_user_reposted_api or tt_get_reposted +
  • +
  • You can get +the videos a user has pinned with +tt_user_pinned_videos_api or +tt_get_pinned +
  • +
  • You can get +who a user is following or follows +a user with +tt_get_following/tt_get_follower or +tt_user_following_api/tt_user_follower_api +
  • Authentication @@ -97,8 +116,8 @@

    Authenticationand then apply for access to the research API: https://developers.tiktok.com/application/research-api -

    Once are approved and have your client key and client secret, you can -authenticate with:

    +

    Once you have been approved and have your client key and client +secret, you can authenticate with:

    @@ -116,31 +135,32 @@

    Usage

    Search Videos

    TikTok uses a fine-grained, yet complicated query -syntax. For convenience, I wrapped this in internally, so you can +syntax. For convenience, a query is constructed internally when you search with a key phrase directly:

    tt_query_videos("#rstats", max_pages = 2L)
     #> 
     ℹ Making initial request
     
    -✔ Making initial request [734ms]
    +✔ Making initial request [774ms]
     #> 
     ℹ Parsing data
     
    -✔ Parsing data [21ms]
    -#> ── search id: NA ───────────────────────────────────────────
    -#> # A tibble: 0 × 11
    -#> # ℹ 11 variables: video_id <lgl>, author_name <chr>,
    +✔ Parsing data [177ms]
    +#> ── search id: NA ───────────────────────────────────────
    +#> # A tibble: 0 × 13
    +#> # ℹ 13 variables: video_id <lgl>, author_name <chr>,
     #> #   view_count <int>, comment_count <int>,
    -#> #   region_code <chr>, create_time <dttm>,
    -#> #   effect_ids <list>, music_id <chr>,
    -#> #   video_description <chr>, hashtag_names <list>,
    -#> #   voice_to_text <chr>
    +#> # share_count <int>, like_count <int>, +#> # region_code <chr>, create_time <dttm>, +#> # effect_ids <list>, music_id <chr>, +#> # video_description <chr>, hashtag_names <list>, +#> # voice_to_text <chr>

    This will match your keyword or phrase against keywords and hashtags -and return up to 200 results (each pages has 100 results and 2 pages are -requested) from today and yesterday. Every whitespace is treated as an -AND operator. To extend the data range, you can set a start and end -(which can be a maximum of 30 days apart, but there is no limit how far -you can go back):

    +and return up to 200 results (each page has 100 results and 2 pages are +requested by default) from today and yesterday. Every whitespace is +treated as an AND operator. To extend the data range, you can set a +start and end (which can be a maximum of 30 days apart, but there is no +limit how far you can go back):

    tt_query_videos("#rstats",
                     max_pages = 2L,
                     start_date = as.Date("2023-11-01"),
    @@ -148,38 +168,39 @@ 

    Search Videos#> ℹ Making initial request -✔ Making initial request [1.1s] +✔ Making initial request [2s] #> ℹ Parsing data -✔ Parsing data [30ms] -#> ── search id: 7336340473469998126 ────────────────────────── -#> # A tibble: 19 × 11 -#> video_id author_name view_count comment_count region_code -#> <chr> <chr> <int> <int> <chr> -#> 1 7306893… statistics… 21 4 DE -#> 2 7306307… learningca… 129 12 US -#> 3 7305014… picanumeros 57 1 ES -#> 4 7302970… smooth.lea… 5568 7 AU -#> 5 7302470… statistics… 45 1 DE -#> 6 7300977… statistics… 1403 0 DE -#> 7 7300931… rigochando 1541 5 MX -#> 8 7300922… elartedeld… 87 0 ES -#> 9 7299987… statistics… 81 1 DE -#> 10 7299657… rigochando 795 5 MX -#> 11 7299342… rigochando 375 1 MX -#> 12 7298966… rigochando 1183 2 MX -#> 13 7296911… biofreelan… 2537 5 MX -#> 14 7296911… biofreelan… 1363 0 MX -#> 15 7296911… biofreelan… 680 1 MX -#> 16 7296688… mrpecners 60 2 US -#> 17 7296518… l_a_kelly 10 5 GB -#> 18 7296498… mrpecners 19 0 US -#> 19 7296288… casaresfel… 266 0 AR -#> # ℹ 6 more variables: create_time <dttm>, -#> # effect_ids <list>, music_id <chr>, -#> # video_description <chr>, hashtag_names <list>, -#> # voice_to_text <chr>

    +✔ Parsing data [63ms] +#> ── search id: 7423432753447932974 ────────────────────── +#> # A tibble: 19 × 13 +#> video_id author_name view_count comment_count +#> <chr> <chr> <int> <int> +#> 1 730689385329705… statistics… 909 4 +#> 2 730630774458222… learningca… 1104 11 +#> 3 730501447636800… picanumeros 4645 8 +#> 4 730297066790799… smooth.lea… 98717 17 +#> 5 730247037950160… statistics… 508 0 +#> 6 730097749816510… statistics… 27387 1 +#> 7 730093147605973… rigochando 2603 4 +#> 8 730092229522312… elartedeld… 765 0 +#> 9 729998705941704… statistics… 1110 1 +#> 10 729965751681473… rigochando 905 4 +#> 11 729934294487885… rigochando 555 0 +#> 12 729896668413454… rigochando 1312 1 +#> 13 729691148659145… biofreelan… 19758 7 +#> 14 729691148625178… biofreelan… 5763 1 +#> 15 729691147878174… biofreelan… 1019 3 +#> 16 729668885660947… mrpecners 657 2 +#> 17 729651863537426… l_a_kelly 514 5 +#> 18 729649864535081… mrpecners 373 0 +#> 19 729628884337898… casaresfel… 274 0 +#> # ℹ 9 more variables: share_count <int>, +#> # like_count <int>, region_code <chr>, +#> # create_time <dttm>, effect_ids <list>, +#> # music_id <chr>, video_description <chr>, +#> # hashtag_names <list>, voice_to_text <chr>

    As said, the query syntax that TikTok uses is a little complicated, as you can use AND, OR and NOT boolean operators on a number of fields ("create_date", "username", @@ -214,7 +235,7 @@

    Search Videos
     query() |>                                # start by using query()
       query_or(field_name = "hashtag_name",   # add an OR condition on the hashtag field
    -           operation = "IN",              # the value should IN the list of hashtags
    +           operation = "IN",              # the value should be IN the list of hashtags
                field_values = "rstats") |>    # the hashtag field does not accept the #-symbol
       query_or(field_name = "keyword",        # add another OR condition
                operation = "IN",
    @@ -286,105 +307,244 @@ 

    Search Videos#> ℹ Making initial request -✔ Making initial request [734ms] +✔ Making initial request [1.1s] #> ℹ Parsing data -✔ Parsing data [17ms] +✔ Parsing data [59ms] search_df -#> ── search id: 7336340473470030894 ────────────────────────── -#> # A tibble: 2 × 11 -#> video_id author_name view_count comment_count region_code -#> <chr> <chr> <int> <int> <chr> -#> 1 72966888… mrpecners 60 2 US -#> 2 72964986… mrpecners 19 0 US -#> # ℹ 6 more variables: create_time <dttm>, -#> # effect_ids <list>, music_id <chr>, -#> # video_description <chr>, hashtag_names <list>, -#> # voice_to_text <chr>

    +#> ── search id: 7423432753447965742 ────────────────────── +#> # A tibble: 2 × 13 +#> video_id author_name view_count comment_count +#> <chr> <chr> <int> <int> +#> 1 7296688856609475… mrpecners 657 2 +#> 2 7296498645350812… mrpecners 373 0 +#> # ℹ 9 more variables: share_count <int>, +#> # like_count <int>, region_code <chr>, +#> # create_time <dttm>, effect_ids <list>, +#> # music_id <chr>, video_description <chr>, +#> # hashtag_names <list>, voice_to_text <chr>

    This will return videos posted in the US or Japan, that have rstats as the only hashtag or as one of the keywords and have a length of "MID", "LONG", or "EXTRA_LONG".1

    -

    Get Basic User Information +

    Get User Information

    There is not really much to getting basic user info, but this is how you can do it:

    -
    -tt_user_info_api(username = c("tiktok", "https://www.tiktok.com/@statisticsglobe"))
    -#> # A tibble: 2 × 8
    -#>   display_name    follower_count following_count is_verified
    -#>   <chr>                    <int>           <int> <lgl>      
    -#> 1 TikTok                78785286              30 TRUE       
    -#> 2 Statistics Glo…            289               1 FALSE      
    -#> # ℹ 4 more variables: likes_count <int>, video_count <int>,
    -#> #   avatar_url <chr>, bio_description <chr>
    +
    tt_user_info_api(username = c("tiktok", "https://www.tiktok.com/@statisticsglobe"))
    +#> 
    +ℹ Getting user tiktok
    +
    +✔ Got user tiktok [508ms]
    +#> 
    +ℹ Getting user statisticsglobe
    +
    +✔ Got user statisticsglobe [518ms]
    +#> # A tibble: 2 × 8
    +#>   is_verified likes_count video_count avatar_url        
    +#>   <lgl>             <int>       <int> <chr>             
    +#> 1 TRUE          330919903        1073 https://p16-pu-si…
    +#> 2 FALSE              1660          92 https://p16-sign-…
    +#> # ℹ 4 more variables: bio_description <chr>,
    +#> #   display_name <chr>, follower_count <int>,
    +#> #   following_count <int>
    +

    If you wish to return the videos of a user, your can use the search +again:

    +
    query() |>
    +  query_and(field_name = "username",
    +            operation = "EQ",
    +            field_values = "statisticsglobe") |>
    +  tt_search_api(start_date = as.Date("2023-11-01"),
    +                end_date = as.Date("2023-11-29"))
    +#> 
    +ℹ Making initial request
    +
    +✔ Making initial request [872ms]
    +#> 
    +ℹ Parsing data
    +
    +✔ Parsing data [65ms]
    +#> ── search id: 7423432753448064046 ──────────────────────
    +#> # A tibble: 5 × 13
    +#>   video_id          author_name view_count comment_count
    +#>   <chr>             <chr>            <int>         <int>
    +#> 1 7306893853297052… statistics…        909             4
    +#> 2 7302470379501604… statistics…        508             0
    +#> 3 7300977498165103… statistics…      27387             1
    +#> 4 7299987059417042… statistics…       1110             1
    +#> 5 7297389484524506… statistics…        538             2
    +#> # ℹ 9 more variables: share_count <int>,
    +#> #   like_count <int>, region_code <chr>,
    +#> #   create_time <dttm>, effect_ids <list>,
    +#> #   music_id <chr>, video_description <chr>,
    +#> #   hashtag_names <list>, voice_to_text <chr>
    +

    You can also find the videos a user has pinned to the top of their +page:

    +
    tt_user_pinned_videos_api(c("tiktok", "https://www.tiktok.com/@smooth.learning.c"))
    +#> 
    +ℹ Getting user tiktok
    +
    +✖ Getting user tiktok [367ms]
    +#> 
    +ℹ Getting user smooth.learning.c
    +
    +✔ Got user smooth.learning.c [571ms]
    +#> # A tibble: 1 × 14
    +#>   pinned_by_user    create_time id      is_stem_verified
    +#>   <chr>                   <int> <chr>   <lgl>           
    +#> 1 smooth.learning.c  1690255097 725959… FALSE           
    +#> # ℹ 10 more variables: region_code <chr>,
    +#> #   video_duration <int>, view_count <int>,
    +#> #   video_description <chr>, comment_count <int>,
    +#> #   hashtag_names <list>, like_count <int>,
    +#> #   music_id <chr>, share_count <int>, username <chr>
    +

    To find out what a user has liked, you can use:

    +
    tt_get_liked("jbgruber")
    +#> 
    +ℹ Getting user jbgruber
    +
    +✔ Got user jbgruber [1.5s]
    +#> # A tibble: 98 × 14
    +#>    id             username create_time video_description
    +#>    <chr>          <chr>          <int> <chr>            
    +#>  1 7355902326877… america…  1712679503 "Stitch with @Mr…
    +#>  2 7268078476102… carterp…  1692231398 "Are you going t…
    +#>  3 7419692903460… okbrune…  1727531892 "Die ganze Wahrh…
    +#>  4 7405633113835… funny_s…  1724258332 "#fyp #fypシ #fu…
    +#>  5 7398532172048… lib0160…  1722605019 "Me and ChatGPT …
    +#>  6 7364763547038… vquasch…  1714742648 "Einige Medien u…
    +#>  7 7346577913858… ct_3003   1710508473 "Diese Platine f…
    +#>  8 7379856141972… lizthed…  1718256663 "Replying to @Ar…
    +#>  9 7415189182865… felixba…  1726483284 "Es geht wieder …
    +#> 10 7422673042553… grueneb…  1728225752 "Was Söder uns e…
    +#> # ℹ 88 more rows
    +#> # ℹ 10 more variables: region_code <chr>,
    +#> #   video_duration <int>, view_count <int>,
    +#> #   like_count <int>, comment_count <int>,
    +#> #   share_count <int>, music_id <chr>,
    +#> #   hashtag_names <list>, is_stem_verified <lgl>,
    +#> #   liked_by_user <chr>
    +

    Note, that making likes public is an opt-in feature of TikTok and +almost nobody has this enabled, so it will give you a lot of +warning…

    +

    What we can usually get is the information who a user follows:

    +
    tt_user_following_api(username = "jbgruber")
    +#> 
    +ℹ Getting user jbgruber
    +
    +✔ Got user jbgruber [296ms]
    +#> # A tibble: 19 × 3
    +#>    display_name          username         following_user
    +#>    <chr>                 <chr>            <chr>         
    +#>  1 SohoBrody             rudeboybrody     jbgruber      
    +#>  2 Last Week Tonight     lastweektonight… jbgruber      
    +#>  3 schlantologie         schlantologie    jbgruber      
    +#>  4 Alex Falcone          alex_falcone     jbgruber      
    +#>  5 dadNRG                dadnrg           jbgruber      
    +#>  6 Einfach Genial Tictok user22690086508… jbgruber      
    +#>  7 noir_concrete_studio  noir_concrete_s… jbgruber      
    +#>  8 fatDumbledore         fatdumbledore13… jbgruber      
    +#>  9 fragdenstaat.de       fragdenstaat.de  jbgruber      
    +#> 10 Erikadbka             erikadbka        jbgruber      
    +#> 11 BÜNDNIS 90/DIE GRÜNEN diegruenen       jbgruber      
    +#> 12 lagedernationclips    lagedernationcl… jbgruber      
    +#> 13 Alexandra Ils         kitty.fantastico jbgruber      
    +#> 14 future infinitive ☸️   lizthedeveloper  jbgruber      
    +#> 15 Tim Achtermeyer       achtermeyer      jbgruber      
    +#> 16 Jay Foreman           jayforeman       jbgruber      
    +#> 17 Cosmo                 whereiswanda     jbgruber      
    +#> 18 Tim Walz              timwalz          jbgruber      
    +#> 19 Shahak Shapira        shahakshapira    jbgruber
    +

    And who they are followed by:

    +
    tt_user_follower_api("https://www.tiktok.com/@tiktok")
    +#> 
    +ℹ Getting user tiktok
    +
    +✔ Got user tiktok [442ms]
    +#> # A tibble: 90 × 3
    +#>    username           display_name     following_user
    +#>    <chr>              <chr>            <chr>         
    +#>  1 galbruwt           reeyyp           tiktok        
    +#>  2 user5235623178011  👑কিং রানা 🥀    tiktok        
    +#>  3 rokyevay07         👑Rokye Vay👑    tiktok        
    +#>  4 babyylious08       babyylious08     tiktok        
    +#>  5 user8283823357     hd❤️‍🩹jaan❤️‍🩹hi❤️‍🩹❤️  tiktok        
    +#>  6 user45628309141722 سامي             tiktok        
    +#>  7 nu.th085           Nâu Thị          tiktok        
    +#>  8 halimeysll         halimeysll       tiktok        
    +#>  9 taru.tristiyanto   Taru Tristiyanto tiktok        
    +#> 10 vng.lan.hng09      Vương Lan Hường  tiktok        
    +#> # ℹ 80 more rows

    Obtain all Comments of a Video

    There is again, not much to talk about when it comes to the comments API. You need to supply a video ID, which you either have already:

    -
    tt_comments_api(video_id = "7302470379501604128")
    -#> 
    -ℹ Making initial request
    -
    -✔ Making initial request [7.2s]
    -#> 
    -ℹ Parsing data
    -
    -✔ Parsing data [18ms]
    -#> ── search id:  ─────────────────────────────────────────────
    -#> # A tibble: 1 × 7
    -#>   text                 video_id create_time id    like_count
    -#>   <chr>                <chr>          <int> <chr>      <int>
    -#> 1 and why would we do… 7302470…  1700243424 7302…          0
    -#> # ℹ 2 more variables: parent_comment_id <chr>,
    -#> #   reply_count <int>
    +
    tt_comments_api(video_id = "7302470379501604128")
    +#> 
    +ℹ Making initial request
    +
    +✔ Making initial request [4.9s]
    +#> 
    +ℹ Parsing data
    +
    +✔ Parsing data [68ms]
    +#> ── search id:  ─────────────────────────────────────────
    +#> # A tibble: 1 × 7
    +#>   create_time id            like_count parent_comment_id
    +#>         <int> <chr>              <int> <chr>            
    +#> 1  1700243424 730248974199…          0 7302470379501604…
    +#> # ℹ 3 more variables: reply_count <int>, text <chr>,
    +#> #   video_id <chr>

    Or you got it from a search:

    -
    tt_comments_api(video_id = search_df$video_id[1])
    -#> 
    -✔ Making initial request [55.7s]
    -#> 
    -ℹ Parsing data
    -
    -✔ Parsing data [18ms]
    -#> ── search id:  ─────────────────────────────────────────────
    -#> # A tibble: 2 × 7
    -#>   like_count parent_comment_id   reply_count text   video_id
    -#>        <int> <chr>                     <int> <chr>  <chr>   
    -#> 1          1 7296688856609475882           1 So co… 7296688…
    -#> 2          0 7296690681388204831           0 Thank… 7296688…
    -#> # ℹ 2 more variables: create_time <int>, id <chr>
    +
    tt_comments_api(video_id = search_df$video_id[1])
    +#> 
    +ℹ Making initial request
    +
    +✔ Making initial request [4.8s]
    +#> 
    +ℹ Parsing data
    +
    +✔ Parsing data [61ms]
    +#> ── search id:  ─────────────────────────────────────────
    +#> # A tibble: 2 × 7
    +#>   create_time id            like_count parent_comment_id
    +#>         <int> <chr>              <int> <chr>            
    +#> 1  1698893206 729669068138…          1 7296688856609475…
    +#> 2  1698893251 729669083429…          0 7296690681388204…
    +#> # ℹ 3 more variables: reply_count <int>, text <chr>,
    +#> #   video_id <chr>

    Or you let the function extract if from a URL to a video:

    -
    tt_comments_api(video_id = "https://www.tiktok.com/@nicksinghtech/video/7195762648716152107?q=%23rstats")
    -#> 
    -ℹ Making initial request
    -
    -✔ Making initial request [2m 16.7s]
    -#> 
    -ℹ Parsing data
    -
    -✔ Parsing data [19ms]
    -#> ── search id:  ─────────────────────────────────────────────
    -#> # A tibble: 96 × 7
    -#>    create_time id               like_count parent_comment_id
    -#>          <int> <chr>                 <int> <chr>            
    -#>  1  1675394834 719576596990925…        314 7195762648716152…
    -#>  2  1675457114 719603344301613…        232 7195762648716152…
    -#>  3  1675458796 719604066348022…        177 7195762648716152…
    -#>  4  1675395061 719576692726561…        166 7195765969909252…
    -#>  5  1675624739 719675339339355…         71 7195762648716152…
    -#>  6  1675465779 719607064381200…         71 7195762648716152…
    -#>  7  1675494738 719619490971140…         27 7195762648716152…
    -#>  8  1675691471 719703995331384…         17 7196040663480222…
    -#>  9  1675656122 719688817955866…         16 7195762648716152…
    -#> 10  1675440749 719596313215706…         16 7195762648716152…
    -#> # ℹ 86 more rows
    -#> # ℹ 3 more variables: reply_count <int>, text <chr>,
    -#> #   video_id <chr>
    +
    tt_comments_api(video_id = "https://www.tiktok.com/@nicksinghtech/video/7195762648716152107?q=%23rstats")
    +#> 
    +ℹ Making initial request
    +
    +✔ Making initial request [5.9s]
    +#> 
    +ℹ Parsing data
    +
    +✔ Parsing data [58ms]
    +#> ── search id:  ─────────────────────────────────────────
    +#> # A tibble: 96 × 7
    +#>    text            video_id create_time id    like_count
    +#>    <chr>           <chr>          <int> <chr>      <int>
    +#>  1 You gotta know… 7195762…  1675394834 7195…        314
    +#>  2 R is the goat … 7195762…  1675457114 7196…        232
    +#>  3 Ppl who like E… 7195762…  1675458796 7196…        177
    +#>  4 Fair but doesn… 7195762…  1675395061 7195…        166
    +#>  5 babe RStudio i… 7195762…  1675624739 7196…         71
    +#>  6 Excel is the b… 7195762…  1675465779 7196…         71
    +#>  7 NOT THE SAS SL… 7195762…  1675494738 7196…         27
    +#>  8 I won't take t… 7195762…  1675691471 7197…         17
    +#>  9 No love for ST… 7195762…  1675656122 7196…         16
    +#> 10 I use SAS 🫡    7195762…  1675440749 7195…         16
    +#> # ℹ 86 more rows
    +#> # ℹ 2 more variables: parent_comment_id <chr>,
    +#> #   reply_count <int>

    And that is essentially it. Note, that if you find the functionality of the Research API lacking, there is nothing that keeps you from using the unofficial API functions.

    @@ -405,26 +565,26 @@

    Dealing with rate you. In this case, you can actually save a search and pick it back up after the reset. To facilitate this, search result objects contain two extra pieces of information in the attributes:

    -
    search_df <- query() |>
    -  query_and(field_name = "region_code",
    -            operation = "IN",
    -            field_values = c("JP", "US")) |>
    -  tt_search_api(start_date = as.Date("2023-11-01"),
    -                end_date = as.Date("2023-11-29"), 
    -                max_pages = 1)
    -#> 
    -ℹ Making initial request
    -
    -✔ Making initial request [1.9s]
    -#> 
    -ℹ Parsing data
    -
    -✔ Parsing data [20ms]
    -
    -attr(search_df, "search_id")
    -#> [1] "7336340473470063662"
    -attr(search_df, "cursor")
    -#> [1] 100
    +
    search_df <- query() |>
    +  query_and(field_name = "region_code",
    +            operation = "IN",
    +            field_values = c("JP", "US")) |>
    +  tt_search_api(start_date = as.Date("2023-11-01"),
    +                end_date = as.Date("2023-11-29"),
    +                max_pages = 1)
    +#> 
    +ℹ Making initial request
    +
    +✔ Making initial request [2.4s]
    +#> 
    +ℹ Parsing data
    +
    +✔ Parsing data [71ms]
    +
    +attr(search_df, "search_id")
    +#> [1] "7423432753448096814"
    +attr(search_df, "cursor")
    +#> [1] 100

    When you want to continue this search, whether because of rate limit or because you decided you want more results, you can do so by providing search_id and cursor to @@ -433,30 +593,30 @@

    Dealing with rate with search_df <- last_query(). search_df will in both cases contain the relevant search_id and cursor in the attributes:

    -
    search_df2 <- query() |>
    -  query_and(field_name = "region_code",
    -            operation = "IN",
    -            field_values = c("JP", "US")) |>
    -  tt_search_api(start_date = as.Date("2023-11-01"),
    -                end_date = as.Date("2023-11-29"), 
    -                
    -                # this part is new
    -                start_cursor = attr(search_df, "cursor"), 
    -                search_id = attr(search_df, "search_id"),
    -                ####
    -                max_pages = 1)
    -#> 
    -ℹ Making initial request
    -
    -✔ Making initial request [5.1s]
    -#> 
    -ℹ Parsing data
    -
    -✔ Parsing data [21ms]
    -attr(search_df2, "search_id")
    -#> [1] "7336340473470063662"
    -attr(search_df2, "cursor")
    -#> [1] 200
    +
    search_df2 <- query() |>
    +  query_and(field_name = "region_code",
    +            operation = "IN",
    +            field_values = c("JP", "US")) |>
    +  tt_search_api(start_date = as.Date("2023-11-01"),
    +                end_date = as.Date("2023-11-29"),
    +
    +                # this part is new
    +                start_cursor = attr(search_df, "cursor"),
    +                search_id = attr(search_df, "search_id"),
    +                ####
    +                max_pages = 1)
    +#> 
    +ℹ Making initial request
    +
    +✔ Making initial request [5.1s]
    +#> 
    +ℹ Parsing data
    +
    +✔ Parsing data [21ms]
    +attr(search_df2, "search_id")
    +#> [1] "7336340473470063662"
    +attr(search_df2, "cursor")
    +#> [1] 200

    Note that the cursor is not equal to how many videos you got before, as the API also counts videos that are “deleted/marked as private by users etc.” [See max_count in Query diff --git a/articles/unofficial-api.html b/articles/unofficial-api.html index 06ead7c..bb61c5e 100644 --- a/articles/unofficial-api.html +++ b/articles/unofficial-api.html @@ -252,7 +252,7 @@

    Get followers and who a user

    Once you have this authorSecId you can look up a maximum of 5,000 followers per account:

    -tt_get_follower(secuid = "MS4wLjABAAAAwiH32UMb5RenqEN7duyfLIeGQgSIx9WtgtOILt55q6ueUXgz4gHqZC5HFx4nabPi",
    +tt_get_follower(secuid = "MS4wLjABAAAAwiH32UMb5RenqEN7duyfLIeGQgSIx9WtgtOILt55q6ueUXgz4gHqZC5HFx4nabPi",
                     verbose = FALSE)
     #> 
     #> # A tibble: 1,116 × 27
    @@ -277,7 +277,7 @@ 

    Get followers and who a user #> # verified <lgl>, diggCount <int>, followerCount <int>, …

    Likewise, you can also check who this account follows:

    -tt_get_following(secuid = "MS4wLjABAAAAwiH32UMb5RenqEN7duyfLIeGQgSIx9WtgtOILt55q6ueUXgz4gHqZC5HFx4nabPi",
    +tt_get_following(secuid = "MS4wLjABAAAAwiH32UMb5RenqEN7duyfLIeGQgSIx9WtgtOILt55q6ueUXgz4gHqZC5HFx4nabPi",
                      verbose = FALSE)
     #> 
     #> # A tibble: 489 × 28
    diff --git a/index.html b/index.html
    index f9fc14b..e7704a1 100644
    --- a/index.html
    +++ b/index.html
    @@ -66,10 +66,10 @@ 

    Feature overview ---+++ @@ -94,26 +94,50 @@

    Feature overviewget user videos

    - + + + + + + + - + - + - + - + + + + + + + + + + + + + + + + + + + diff --git a/pkgdown.yml b/pkgdown.yml index aa5e89b..70c2b73 100644 --- a/pkgdown.yml +++ b/pkgdown.yml @@ -4,7 +4,7 @@ pkgdown_sha: ~ articles: research-api: research-api.html unofficial-api: unofficial-api.html -last_built: 2024-10-08T14:16Z +last_built: 2024-10-08T16:01Z urls: reference: https://jbgruber.github.io/traktok/reference article: https://jbgruber.github.io/traktok/articles diff --git a/reference/index.html b/reference/index.html index 2c594da..5b2490c 100644 --- a/reference/index.html +++ b/reference/index.html @@ -96,7 +96,13 @@

    All functionstt_get_following_hidden() tt_get_follower_hidden() tt_get_follower() tt_get_following() + tt_get_follower() tt_get_following() + + +
    Get followers and following of users
    +
    + + tt_get_following_hidden() tt_get_follower_hidden()
    Get followers and following of a user from the hidden API
    @@ -108,7 +114,7 @@

    All functionstt_playlist_api() + tt_playlist_api() tt_playlist()
    Lookup TikTok playlist using the research API
    @@ -158,6 +164,18 @@

    All functionstt_user_liked_videos_api() tt_get_liked() + +
    Lookup which videos were liked by a user using the research API
    +

    + + tt_user_pinned_videos_api() tt_get_pinned() + +
    +
    Lookup which videos were pinned by a user using the research API
    +
    + + tt_user_reposted_api() tt_get_reposted() +
    Lookup which videos were liked by a user using the research API
    diff --git a/reference/tt_get_follower.html b/reference/tt_get_follower.html index fa84168..a9b618c 100644 --- a/reference/tt_get_follower.html +++ b/reference/tt_get_follower.html @@ -1,8 +1,91 @@ - - - - - - - + +Get followers and following of users — tt_get_follower • traktok + Skip to contents + + +
    +
    +
    + +
    +

    [Both]

    +

    Get usernames of users who follows a user (tt_get_follower) or get who a + user is following (tt_get_following).

    +
    + +
    +

    Usage

    +
    tt_get_follower(...)
    +
    +tt_get_following(...)
    +
    + +
    +

    Arguments

    + + +
    ...
    +

    arguments passed to tt_user_follower_api or +tt_get_follower_hidden. To use the research API, include token +(e.g., token = NULL).

    + +
    +
    +

    Value

    +

    a data.frame

    +
    + +
    + + +
    + + + +
    + + + + + + diff --git a/reference/tt_get_following.html b/reference/tt_get_following.html index fa84168..9044733 100644 --- a/reference/tt_get_following.html +++ b/reference/tt_get_following.html @@ -1,8 +1,8 @@ - + - + diff --git a/reference/tt_get_following_hidden.html b/reference/tt_get_following_hidden.html index 8bb7e44..63193f4 100644 --- a/reference/tt_get_following_hidden.html +++ b/reference/tt_get_following_hidden.html @@ -35,7 +35,7 @@ diff --git a/reference/tt_get_pinned.html b/reference/tt_get_pinned.html new file mode 100644 index 0000000..34d7f6d --- /dev/null +++ b/reference/tt_get_pinned.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/reference/tt_get_reposted.html b/reference/tt_get_reposted.html new file mode 100644 index 0000000..4d105cb --- /dev/null +++ b/reference/tt_get_reposted.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/reference/tt_playlist.html b/reference/tt_playlist.html new file mode 100644 index 0000000..02e3141 --- /dev/null +++ b/reference/tt_playlist.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/reference/tt_playlist_api.html b/reference/tt_playlist_api.html index 29c89c3..c4ac332 100644 --- a/reference/tt_playlist_api.html +++ b/reference/tt_playlist_api.html @@ -33,7 +33,7 @@
    @@ -43,7 +43,9 @@

    Usage

    -
    tt_playlist_api(playlist_id, verbose = TRUE, token = NULL)
    +
    tt_playlist_api(playlist_id, verbose = TRUE, token = NULL)
    +
    +tt_playlist(playlist_id, verbose = TRUE, token = NULL)
    diff --git a/reference/tt_user_follower_api.html b/reference/tt_user_follower_api.html index 46d2791..4a9b607 100644 --- a/reference/tt_user_follower_api.html +++ b/reference/tt_user_follower_api.html @@ -100,7 +100,7 @@

    Examples# OR tt_user_following_api("https://www.tiktok.com/@tiktok") # OR -tt_get_follower("https://www.tiktok.com/@tiktok") +tt_get_follower("https://www.tiktok.com/@tiktok") } # }

    diff --git a/reference/tt_user_liked_videos_api.html b/reference/tt_user_liked_videos_api.html index 4e0ed41..e0632ca 100644 --- a/reference/tt_user_liked_videos_api.html +++ b/reference/tt_user_liked_videos_api.html @@ -102,7 +102,7 @@

    Value

    Examples

    if (FALSE) { # \dontrun{
    -tt_user_liked_videos_api("jbgruber")
    +tt_get_liked("jbgruber")
     # OR
     tt_user_liked_videos_api("https://www.tiktok.com/@tiktok")
     # OR
    diff --git a/reference/tt_user_pinned_videos_api.html b/reference/tt_user_pinned_videos_api.html
    new file mode 100644
    index 0000000..a188cc7
    --- /dev/null
    +++ b/reference/tt_user_pinned_videos_api.html
    @@ -0,0 +1,121 @@
    +
    +Lookup which videos were pinned by a user using the research API — tt_user_pinned_videos_api • traktok
    +    Skip to contents
    +
    +
    +    
    +
    +
    + +
    +

    [Works on: Research API]

    +
    + +
    +

    Usage

    +
    tt_user_pinned_videos_api(
    +  username,
    +  fields = "all",
    +  cache = TRUE,
    +  verbose = TRUE,
    +  token = NULL
    +)
    +
    +tt_get_pinned(
    +  username,
    +  fields = "all",
    +  cache = TRUE,
    +  verbose = TRUE,
    +  token = NULL
    +)
    +
    + +
    +

    Arguments

    + + +
    fields
    +

    The fields to be returned (defaults to all)

    + + +
    cache
    +

    should progress be saved in the current session? It can then be +retrieved with last_query() if an error occurs. But the function +will use extra memory.

    + + +
    verbose
    +

    should the function print status updates to the screen?

    + + +
    token
    +

    The authentication token (usually supplied automatically after +running auth_research once)

    + +
    +
    +

    Value

    +

    A data.frame of parsed TikTok videos the user has posted

    +
    + +
    +

    Examples

    +
    if (FALSE) { # \dontrun{
    +tt_get_pinned("jbgruber")
    +# OR
    +tt_user_pinned_videos_api("https://www.tiktok.com/@tiktok")
    +# OR
    +tt_user_pinned_videos_api("https://www.tiktok.com/@tiktok")
    +} # }
    +
    +
    +
    + + +
    + + + +
    + + + + + + + diff --git a/reference/tt_user_reposted_api.html b/reference/tt_user_reposted_api.html new file mode 100644 index 0000000..ca67836 --- /dev/null +++ b/reference/tt_user_reposted_api.html @@ -0,0 +1,134 @@ + +Lookup which videos were liked by a user using the research API — tt_user_reposted_api • traktok + Skip to contents + + +
    +
    +
    + +
    +

    [Works on: Research API]

    +
    + +
    +

    Usage

    +
    tt_user_reposted_api(
    +  username,
    +  fields = "all",
    +  max_pages = 1,
    +  cache = TRUE,
    +  verbose = TRUE,
    +  token = NULL
    +)
    +
    +tt_get_reposted(
    +  username,
    +  fields = "all",
    +  max_pages = 1,
    +  cache = TRUE,
    +  verbose = TRUE,
    +  token = NULL
    +)
    +
    + +
    +

    Arguments

    + + +
    username
    +

    name(s) of the user(s) to be queried

    + + +
    fields
    +

    The fields to be returned (defaults to all)

    + + +
    max_pages
    +

    results are returned in batches/pages with 100 videos. How +many should be requested before the function stops?

    + + +
    cache
    +

    should progress be saved in the current session? It can then be +retrieved with last_query() if an error occurs. But the function +will use extra memory.

    + + +
    verbose
    +

    should the function print status updates to the screen?

    + + +
    token
    +

    The authentication token (usually supplied automatically after +running auth_research once)

    + +
    +
    +

    Value

    +

    A data.frame of parsed TikTok videos the user has posted

    +
    + +
    +

    Examples

    +
    if (FALSE) { # \dontrun{
    +tt_get_reposted("jbgruber")
    +# OR
    +tt_user_reposted_api("https://www.tiktok.com/@tiktok")
    +# OR
    +tt_user_reposted_api("https://www.tiktok.com/@tiktok")
    +
    +# note: none of these work because nobody has this enabled!
    +} # }
    +
    +
    +
    + + +
    + + + +
    + + + + + + + diff --git a/search.json b/search.json index 582d7ea..53e31a2 100644 --- a/search.json +++ b/search.json @@ -1 +1 @@ -[{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"authentication","dir":"Articles","previous_headings":"","what":"Authentication","title":"Research API","text":"get access Research API, need : eligible; create developer account; apply access research API: https://developers.tiktok.com/application/research-api approved client key client secret, can authenticate : recommended run function without arguments, key secret can entered pop mask remain unencrypted R history script. function runs authentication saves resulting token encrypted hard drive. Just run case credentials change.","code":"library(traktok) auth_research()"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"search-videos","dir":"Articles","previous_headings":"Usage","what":"Search Videos","title":"Research API","text":"TikTok uses fine-grained, yet complicated query syntax. convenience, wrapped internally, can search key phrase directly: match keyword phrase keywords hashtags return 200 results (pages 100 results 2 pages requested) today yesterday. Every whitespace treated operator. extend data range, can set start end (can maximum 30 days apart, limit far can go back): said, query syntax TikTok uses little complicated, can use , boolean operators number fields (\"create_date\", \"username\", \"region_code\", \"video_id\", \"hashtag_name\", \"keyword\", \"music_id\", \"effect_id\", \"video_length\"): make easier use, traktok uses tidyverse style approach building queries. example, get query matches #rstats keywords hashtags, need build query like : #rstats found either hashtag keywords video, video returned. Besides checking EQual, can also use one operations: makes building queries relatively complex, allows fine-grained searches TikTok data: return videos posted US Japan, rstats hashtag one keywords length \"MID\", \"LONG\", \"EXTRA_LONG\".1","code":"tt_query_videos(\"#rstats\", max_pages = 2L) #> ℹ Making initial request ✔ Making initial request [734ms] #> ℹ Parsing data ✔ Parsing data [21ms] #> ── search id: NA ─────────────────────────────────────────── #> # A tibble: 0 × 11 #> # ℹ 11 variables: video_id , author_name , #> # view_count , comment_count , #> # region_code , create_time , #> # effect_ids , music_id , #> # video_description , hashtag_names , #> # voice_to_text tt_query_videos(\"#rstats\", max_pages = 2L, start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\")) #> ℹ Making initial request ✔ Making initial request [1.1s] #> ℹ Parsing data ✔ Parsing data [30ms] #> ── search id: 7336340473469998126 ────────────────────────── #> # A tibble: 19 × 11 #> video_id author_name view_count comment_count region_code #> #> 1 7306893… statistics… 21 4 DE #> 2 7306307… learningca… 129 12 US #> 3 7305014… picanumeros 57 1 ES #> 4 7302970… smooth.lea… 5568 7 AU #> 5 7302470… statistics… 45 1 DE #> 6 7300977… statistics… 1403 0 DE #> 7 7300931… rigochando 1541 5 MX #> 8 7300922… elartedeld… 87 0 ES #> 9 7299987… statistics… 81 1 DE #> 10 7299657… rigochando 795 5 MX #> 11 7299342… rigochando 375 1 MX #> 12 7298966… rigochando 1183 2 MX #> 13 7296911… biofreelan… 2537 5 MX #> 14 7296911… biofreelan… 1363 0 MX #> 15 7296911… biofreelan… 680 1 MX #> 16 7296688… mrpecners 60 2 US #> 17 7296518… l_a_kelly 10 5 GB #> 18 7296498… mrpecners 19 0 US #> 19 7296288… casaresfel… 266 0 AR #> # ℹ 6 more variables: create_time , #> # effect_ids , music_id , #> # video_description , hashtag_names , #> # voice_to_text query() |> # start by using query() query_or(field_name = \"hashtag_name\", # add an OR condition on the hashtag field operation = \"IN\", # the value should IN the list of hashtags field_values = \"rstats\") |> # the hashtag field does not accept the #-symbol query_or(field_name = \"keyword\", # add another OR condition operation = \"IN\", field_values = \"#rstats\") #> S3 #> └─or: #> ├─ #> │ ├─field_name: \"hashtag_name\" #> │ ├─operation: \"IN\" #> │ └─field_values: #> │ └─\"rstats\" #> └─ #> ├─field_name: \"keyword\" #> ├─operation: \"IN\" #> └─field_values: #> └─\"#rstats\" search_df <- query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> query_or(field_name = \"hashtag_name\", operation = \"EQ\", # rstats is the only hashtag field_values = \"rstats\") |> query_or(field_name = \"keyword\", operation = \"IN\", # rstats is one of the keywords field_values = \"rstats\") |> query_not(operation = \"EQ\", field_name = \"video_length\", field_values = \"SHORT\") |> tt_search_api(start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\")) #> ℹ Making initial request ✔ Making initial request [734ms] #> ℹ Parsing data ✔ Parsing data [17ms] search_df #> ── search id: 7336340473470030894 ────────────────────────── #> # A tibble: 2 × 11 #> video_id author_name view_count comment_count region_code #> #> 1 72966888… mrpecners 60 2 US #> 2 72964986… mrpecners 19 0 US #> # ℹ 6 more variables: create_time , #> # effect_ids , music_id , #> # video_description , hashtag_names , #> # voice_to_text "},{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"get-basic-user-information","dir":"Articles","previous_headings":"Usage","what":"Get Basic User Information","title":"Research API","text":"really much getting basic user info, can :","code":"tt_user_info_api(username = c(\"tiktok\", \"https://www.tiktok.com/@statisticsglobe\")) #> # A tibble: 2 × 8 #> display_name follower_count following_count is_verified #> #> 1 TikTok 78785286 30 TRUE #> 2 Statistics Glo… 289 1 FALSE #> # ℹ 4 more variables: likes_count , video_count , #> # avatar_url , bio_description "},{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"obtain-all-comments-of-a-video","dir":"Articles","previous_headings":"Usage","what":"Obtain all Comments of a Video","title":"Research API","text":", much talk comes comments API. need supply video ID, either already: got search: let function extract URL video: essentially . Note, find functionality Research API lacking, nothing keeps using unofficial API functions.","code":"tt_comments_api(video_id = \"7302470379501604128\") #> ℹ Making initial request ✔ Making initial request [7.2s] #> ℹ Parsing data ✔ Parsing data [18ms] #> ── search id: ───────────────────────────────────────────── #> # A tibble: 1 × 7 #> text video_id create_time id like_count #> #> 1 and why would we do… 7302470… 1700243424 7302… 0 #> # ℹ 2 more variables: parent_comment_id , #> # reply_count tt_comments_api(video_id = search_df$video_id[1]) #> ✔ Making initial request [55.7s] #> ℹ Parsing data ✔ Parsing data [18ms] #> ── search id: ───────────────────────────────────────────── #> # A tibble: 2 × 7 #> like_count parent_comment_id reply_count text video_id #> #> 1 1 7296688856609475882 1 So co… 7296688… #> 2 0 7296690681388204831 0 Thank… 7296688… #> # ℹ 2 more variables: create_time , id tt_comments_api(video_id = \"https://www.tiktok.com/@nicksinghtech/video/7195762648716152107?q=%23rstats\") #> ℹ Making initial request ✔ Making initial request [2m 16.7s] #> ℹ Parsing data ✔ Parsing data [19ms] #> ── search id: ───────────────────────────────────────────── #> # A tibble: 96 × 7 #> create_time id like_count parent_comment_id #> #> 1 1675394834 719576596990925… 314 7195762648716152… #> 2 1675457114 719603344301613… 232 7195762648716152… #> 3 1675458796 719604066348022… 177 7195762648716152… #> 4 1675395061 719576692726561… 166 7195765969909252… #> 5 1675624739 719675339339355… 71 7195762648716152… #> 6 1675465779 719607064381200… 71 7195762648716152… #> 7 1675494738 719619490971140… 27 7195762648716152… #> 8 1675691471 719703995331384… 17 7196040663480222… #> 9 1675656122 719688817955866… 16 7195762648716152… #> 10 1675440749 719596313215706… 16 7195762648716152… #> # ℹ 86 more rows #> # ℹ 3 more variables: reply_count , text , #> # video_id "},{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"dealing-with-rate-limits-and-continuing-old-searches","dir":"Articles","previous_headings":"","what":"Dealing with rate limits and continuing old searches","title":"Research API","text":"moment writing vignette, TikTok rate limits Research API follows: Currently, daily limit set 1000 requests per day, allowing obtain 100,000 records per day across APIs. (Video Comments API can return 100 records per request). daily quota gets reset 12 UTC. [Source] Depending like , might enough . case, can actually save search pick back reset. facilitate , search result objects contain two extra pieces information attributes: want continue search, whether rate limit decided want results, can providing search_id cursor tt_search_api. search cut short rate limit another issue, can retrieve results already received search_df <- last_query(). search_df cases contain relevant search_id cursor attributes: Note cursor equal many videos got , API also counts videos “deleted/marked private users etc.” [See max_count Query Videos].","code":"search_df <- query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> tt_search_api(start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\"), max_pages = 1) #> ℹ Making initial request ✔ Making initial request [1.9s] #> ℹ Parsing data ✔ Parsing data [20ms] attr(search_df, \"search_id\") #> [1] \"7336340473470063662\" attr(search_df, \"cursor\") #> [1] 100 search_df2 <- query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> tt_search_api(start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\"), # this part is new start_cursor = attr(search_df, \"cursor\"), search_id = attr(search_df, \"search_id\"), #### max_pages = 1) #> ℹ Making initial request ✔ Making initial request [5.1s] #> ℹ Parsing data ✔ Parsing data [21ms] attr(search_df2, \"search_id\") #> [1] \"7336340473470063662\" attr(search_df2, \"cursor\") #> [1] 200"},{"path":"https://jbgruber.github.io/traktok/articles/unofficial-api.html","id":"authentication","dir":"Articles","previous_headings":"","what":"Authentication","title":"Unofficial API","text":"easiest way get cookies needed authentication export necessary cookies browser using browser extension (logging TikTok.com least ). can recommend “Get cookies.txt” Chromium based browsers “cookies.txt” Firefox (note almost browsers used today based one ). Save cookies.txt file, look something like : matter download cookies just ones specific TikTok, use cookiemonster package deal . read cookies specific encrypted file, simply use: ’s ! traktok access cookies whenever necessary.","code":"# Netscape HTTP Cookie File # https://curl.haxx.se/rfc/cookie_spec.html # This is a generated file! Do not edit. .tiktok.com TRUE / TRUE 1728810805 cookie-consent {%22ga%22:true%2C%22af%... .tiktok.com TRUE / TRUE 1700471788 passport_csrf_token e07d3487c11ce5258a3... .tiktok.com TRUE / FALSE 1700471788 passport_csrf_token_default e07d3487c11... #HttpOnly_.tiktok.com TRUE / TRUE 1700493610 multi_sids 71573310862246389... #HttpOnly_.tiktok.com TRUE / TRUE 1700493610 cmpl_token AgQQAPORF-RO0rNtH... ... cookiemonster::add_cookies(\"tiktok.com_cookies.txt\")"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/articles/unofficial-api.html","id":"search-videos","dir":"Articles","previous_headings":"Usage","what":"Search videos","title":"Unofficial API","text":"search videos, can use either tt_search tt_search_hidden, , long token Research API. get first two pages search results (one page 12 videos), can use command: already gives pretty much information want videos found.","code":"rstats_df <- tt_search_hidden(\"#rstats\", max_pages = 2) #> ℹ Getting page 1 ⏲ waiting 0.5 seconds ℹ Getting page 1 ✔ Got page 1. Found 12 videos. [1.9s] #> ℹ Getting page 2 ✔ Got page 2. Found 12 videos. [690ms] rstats_df #> # A tibble: 24 × 20 #> video_id video_timestamp video_url video_length video_title #> #> 1 71151144… 2022-06-30 19:17:53 https://… 135 \"R for Beg… #> 2 72522261… 2023-07-05 07:01:45 https://… 36 \"Wow!!! TH… #> 3 72420686… 2023-06-07 22:05:16 https://… 34 \"R GRAPHIC… #> 4 72134135… 2023-03-22 16:49:12 https://… 6 \"R and me … #> 5 72576898… 2023-07-20 00:23:40 https://… 56 \"Pie chart… #> 6 72999870… 2023-11-10 23:58:21 https://… 51 \"Quick R Q… #> 7 72783048… 2023-09-13 13:40:21 https://… 36 \"Quick R Q… #> 8 73029706… 2023-11-19 00:56:09 https://… 163 \"What is c… #> 9 71670108… 2022-11-17 15:42:56 https://… 58 \"Here’s an… #> 10 72933174… 2023-10-24 00:36:48 https://… 9 \"#CapCut #… #> # ℹ 14 more rows #> # ℹ 15 more variables: video_diggcount , #> # video_sharecount , video_commentcount , #> # video_playcount , video_is_ad , author_name , #> # author_nickname , author_followercount , #> # author_followingcount , author_heartcount , #> # author_videocount , author_diggcount , …"},{"path":"https://jbgruber.github.io/traktok/articles/unofficial-api.html","id":"get-metadata-and-download-videos","dir":"Articles","previous_headings":"Usage","what":"Get metadata and download videos","title":"Unofficial API","text":"However, can obtain information, importantly video file, using tt_videos: Per default, function waits one ten seconds (chosen random) making two calls, make obvious data scraped TikTok. can speed process (risk), changing sleep_pool argument, controls minimum maximum number seconds wait: scraping lot URLs, function might fail eventually, due poor connection TikTok blocking requests. therefore usually makes sense save progress cache directory: Note video files downloaded dir directory (working directory default), independently cache directory. information feel missing data.frame tt_videos returns, can look raw, unparsed json data using: Parsing result list using fromJSON, results rather complex nested list. can look see data interested ","code":"rstats_df2 <- tt_videos(rstats_df$video_url[1:2], save_video = TRUE) #> ℹ Getting video 7115114419314560298 ⏲ waiting 0.2 seconds ℹ Getting video 7115114419314560298 ✔ Got video 7115114419314560298 (1/2). File size: 2.5 Mb. [2.5s] #> ℹ Getting video 7252226153828584731 ✔ Got video 7252226153828584731 (2/2). File size: 1.7 Mb. [999ms] rstats_df2 #> # A tibble: 2 × 19 #> video_id video_url video_timestamp video_length video_title #> #> 1 711511441… https://… 2022-06-30 19:17:53 135 R for Begi… #> 2 725222615… https://… 2023-07-05 07:01:45 36 Wow!!! THI… #> # ℹ 14 more variables: video_locationcreated , #> # video_diggcount , video_sharecount , #> # video_commentcount , video_playcount , #> # author_username , author_nickname , #> # author_bio , download_url , html_status , #> # music , challenges , is_classified , #> # video_fn rstats_df3 <- tt_videos(rstats_df$video_url[3:4], save_video = TRUE, sleep_pool = 0.1) #> ℹ Getting video 7242068680484408581 ⏲ waiting 0.1 seconds ℹ Getting video 7242068680484408581 ✔ Got video 7242068680484408581 (1/2). File size: 1.8 Mb. [2.6s] #> ℹ Getting video 7213413598998056234 ✔ Got video 7213413598998056234 (2/2). File size: 598.1 Kb. [1.7s] rstats_df3 #> # A tibble: 2 × 19 #> video_id video_url video_timestamp video_length video_title #> #> 1 724206868… https://… 2023-06-07 22:05:16 34 \"R GRAPHIC… #> 2 721341359… https://… 2023-03-22 16:49:12 6 \"R and me … #> # ℹ 14 more variables: video_locationcreated , #> # video_diggcount , video_sharecount , #> # video_commentcount , video_playcount , #> # author_username , author_nickname , #> # author_bio , download_url , html_status , #> # music , challenges , is_classified , #> # video_fn rstats_df3 <- tt_videos(rstats_df$video_url[5:6], cache_dir = \"rstats\") #> ℹ Getting video 7257689890245201153 ⏲ waiting 1.7 seconds ℹ Getting video 7257689890245201153 ✔ Got video 7257689890245201153 (1/2). File size: 1.7 Mb. [2.6s] #> ℹ Getting video 7299987059417042209 ✔ Got video 7299987059417042209 (2/2). File size: 1.2 Mb. [1.8s] list.files(\"rstats\") #> [1] \"7257689890245201153.json\" \"7299987059417042209.json\" rstats_list1 <- tt_request_hidden(rstats_df$video_url[1]) |> jsonlite::fromJSON()"},{"path":"https://jbgruber.github.io/traktok/articles/unofficial-api.html","id":"get-followers-and-who-a-user-is-following","dir":"Articles","previous_headings":"Usage","what":"Get followers and who a user is following","title":"Unofficial API","text":"Getting followers user following (moment?) little tricky use, since TikTok blocks requests users profile page anti-scraping measures. circumvent , can open users page browser right-click show source code:1 can search copy authorSecId value: authorSecId can look maximum 5,000 followers per account: Likewise, can also check account follows:","code":"tt_get_follower(secuid = \"MS4wLjABAAAAwiH32UMb5RenqEN7duyfLIeGQgSIx9WtgtOILt55q6ueUXgz4gHqZC5HFx4nabPi\", verbose = FALSE) #> #> # A tibble: 1,116 × 27 #> avatarLarger avatarMedium avatarThumb commentSetting #> #> 1 https://p16-sign-sg.tik… https://p16… https://p1… 0 #> 2 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 3 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 4 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 5 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 6 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 7 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 8 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 9 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 10 https://p16-sign-va.tik… https://p16… https://p1… 0 #> # ℹ 1,106 more rows #> # ℹ 23 more variables: downloadSetting , duetSetting , #> # ftc , id , isADVirtual , nickname , #> # openFavorite , privateAccount , relation , #> # secUid , secret , signature , #> # stitchSetting , ttSeller , uniqueId , #> # verified , diggCount , followerCount , … tt_get_following(secuid = \"MS4wLjABAAAAwiH32UMb5RenqEN7duyfLIeGQgSIx9WtgtOILt55q6ueUXgz4gHqZC5HFx4nabPi\", verbose = FALSE) #> #> # A tibble: 489 × 28 #> avatarLarger avatarMedium avatarThumb commentSetting #> #> 1 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 2 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 3 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 4 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 5 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 6 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 7 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 8 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 9 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 10 https://p16-sign-va.tik… https://p16… https://p1… 0 #> # ℹ 479 more rows #> # ℹ 24 more variables: downloadSetting , duetSetting , #> # ftc , id , isADVirtual , nickname , #> # openFavorite , privateAccount , relation , #> # secUid , secret , signature , #> # stitchSetting , ttSeller , uniqueId , #> # verified , diggCount , followerCount , … list.files(pattern = \".mp4\") |> unlink() unlink(\"rstats\", recursive = TRUE)"},{"path":"https://jbgruber.github.io/traktok/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Johannes B. Gruber. Author, maintainer.","code":""},{"path":"https://jbgruber.github.io/traktok/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Gruber, Johannes B. (2023). traktok. R package scrape data TikTok. R package version 0.0.4.9000. https://github.com/JBGruber/traktok.","code":"@Manual{, title = {traktok. Getting TikTok data through the official and unofficial APIs}, author = {Johannes B. Gruber}, year = {2023}, url = {https://github.com/JBGruber/traktok}, note = {R package version 0.0.4.9000}, }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/index.html","id":"feature-overview","dir":"","previous_headings":"","what":"Feature overview","title":"Collecting TikTok Data","text":"goal traktok provide easy access TikTok data. package one started R port Deen Freelon’s Pyktok Python module (though complete rewrite without Python dependencies). now covers functions secret hidden API TikTok using show/search/play videos Website official Research API. Since Research API misses important features (since everyone access ) can often make sense still use hidden API mocks requests browser. However, important disclaimer hidden API applies: program may stop working suddenly TikTok changes stores data (see Freelon, 2018). However, last times, fixed rather quickly (e.g., #12).","code":""},{"path":"https://jbgruber.github.io/traktok/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Collecting TikTok Data","text":"can install development version traktok GitHub :","code":"# install.packages(\"remotes\") remotes::install_github(\"JBGruber/traktok\")"},{"path":"https://jbgruber.github.io/traktok/index.html","id":"in-research","dir":"","previous_headings":"","what":"In Research","title":"Collecting TikTok Data","text":"research papers projects used traktok gather data: Hohner, J., Kakavand, ., & Rothut, S. (2024). Analyzing Radical Visuals Scale: Far-Right Groups Mobilize TikTok. Journal Digital Social Research, 6(1), 10–30. https://doi.org/10.33621/jdsr.v6i1.200 Bach, P., Gitomer, ., Devries, M., Walker, C., Deyoe, D., Atienza-Bathelemy, J., Foucault Welles, B., Freelon, D., & Zulli, D. (2023, October). Stitching Politics Identity TikTok. Panel presented AoIR2023: 24th Annual Conference Association Internet Researchers. Philadelphia, PA, USA: AoIR. Retrieved http://spir.aoir.org Wirz, D. S., Zai, F., Vogler, D., Urman, ., & Eisenegger, M. (2023). Die Qualität von Schweizer Medien auf Instagram und TikTok. https://doi.org/10.5167/UZH-238605 Giglietto, F. (2024). Dashboard: TikTok Coordinated Sharing Network. https://fabiogiglietto.github.io/tiktok_csbn/tt_viz.html used traktok research paper project, please extend list Pull Request create issue","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":null,"dir":"Reference","previous_headings":"","what":"Check whether you are authenticated — auth_check","title":"Check whether you are authenticated — auth_check","text":"Check necessary token cookies stored computer already. default, function checks authentication research hidden API. learn can authenticate, look vignette research (vignette(\"research-api\", package = \"traktok\")) hidden (vignette(\"unofficial-api\", package = \"traktok\")) API.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Check whether you are authenticated — auth_check","text":"","code":"auth_check(research = TRUE, hidden = TRUE, silent = FALSE)"},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Check whether you are authenticated — auth_check","text":"research, hidden turn check /research hidden API. silent return check(s) successful, status screen","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Check whether you are authenticated — auth_check","text":"logical vector (invisible)","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Check whether you are authenticated — auth_check","text":"","code":"auth_check() #> Error in cookiemonster::get_cookies(\"^(www.)*tiktok.com\") : #> The directory ~/.cache/r_cookies does not contain any cookies yet. Use #> `add_cookies()` to store cookies for a website (see `vignette(\"cookies\", #> \"cookiemonster\")` for details)."},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Authenticate for the hidden/unofficial API — auth_hidden","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"Guides authentication hidden/unofficial API#'","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"","code":"auth_hidden(cookiefile, live = interactive())"},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"cookiefile optional path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication. live opens Chromium browser guide auth process.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"nothing. Called set authentication","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"","code":"if (FALSE) { # \\dontrun{ # to run through the steps of authentication auth_hidden() # or point to a cookie file directly auth_hidden(\"www.tiktok.com_cookies.txt\") } # }"},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":null,"dir":"Reference","previous_headings":"","what":"Authenticate for the official research API — auth_research","title":"Authenticate for the official research API — auth_research","text":"Authenticate official research API","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Authenticate for the official research API — auth_research","text":"","code":"auth_research(client_key, client_secret)"},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Authenticate for the official research API — auth_research","text":"client_key Client key authentication client_secret Client secret authentication","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Authenticate for the official research API — auth_research","text":"authentication token","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Authenticate for the official research API — auth_research","text":"need apply access API get key secret TikTok. See https://developers.tiktok.com/products/research-api/ information.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Authenticate for the official research API — auth_research","text":"","code":"if (FALSE) { # \\dontrun{ auth_research(client_key, client_secret) } # }"},{"path":"https://jbgruber.github.io/traktok/reference/last_query.html","id":null,"dir":"Reference","previous_headings":"","what":"Retrieve most recent query — last_query","title":"Retrieve most recent query — last_query","text":"tt_search_api tt_comments_api fail already getting several pages, can use function get videos retrieved far memory. work session crashed. case, look tempdir() RDS file last resort.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/last_query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Retrieve most recent query — last_query","text":"","code":"last_query() last_comments()"},{"path":"https://jbgruber.github.io/traktok/reference/last_query.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Retrieve most recent query — last_query","text":"list unparsed videos","code":""},{"path":"https://jbgruber.github.io/traktok/reference/print.traktok_query.html","id":null,"dir":"Reference","previous_headings":"","what":"Print a traktok query — print.traktok_query","title":"Print a traktok query — print.traktok_query","text":"Print traktok query tree","code":""},{"path":"https://jbgruber.github.io/traktok/reference/print.traktok_query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Print a traktok query — print.traktok_query","text":"","code":"# S3 method for class 'traktok_query' print(x, ...)"},{"path":"https://jbgruber.github.io/traktok/reference/print.traktok_query.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Print a traktok query — print.traktok_query","text":"x object class traktok_query ... Additional arguments passed lobstr::tree","code":""},{"path":"https://jbgruber.github.io/traktok/reference/print.traktok_query.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Print a traktok query — print.traktok_query","text":"","code":"query() |> query_and(field_name = \"hashtag_name\", operation = \"EQ\", field_values = \"rstats\") |> print() #> S3 #> └─and: #> └─ #> ├─field_name: \"hashtag_name\" #> ├─operation: \"EQ\" #> └─field_values: #> └─\"rstats\""},{"path":"https://jbgruber.github.io/traktok/reference/print.tt_results.html","id":null,"dir":"Reference","previous_headings":"","what":"Print search result — print.tt_results","title":"Print search result — print.tt_results","text":"Print traktok search results","code":""},{"path":"https://jbgruber.github.io/traktok/reference/print.tt_results.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Print search result — print.tt_results","text":"","code":"# S3 method for class 'tt_results' print(x, ...)"},{"path":"https://jbgruber.github.io/traktok/reference/print.tt_results.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Print search result — print.tt_results","text":"x object class tt_results ... used.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a traktok query — query","title":"Create a traktok query — query","text":"Create traktok query given parameters.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a traktok query — query","text":"","code":"query(and = NULL, or = NULL, not = NULL) query_and(q, field_name, operation, field_values) query_or(q, field_name, operation, field_values) query_not(q, field_name, operation, field_values)"},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a traktok query — query","text":", , list //conditions. Must contain one multiple lists field_name, operation, field_values (see example). q traktok query created query. field_name field name query . One : \"create_date\", \"username\", \"region_code\", \"video_id\", \"hashtag_name\", \"keyword\", \"music_id\", \"effect_id\", \"video_length\". operation One : \"EQ\", \"\", \"GT\", \"GTE\", \"LT\", \"LTE\". field_values vector values search .","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a traktok query — query","text":"traktok query.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Create a traktok query — query","text":"TikTok's query consists rather complicated lists dividing query elements , : : conditions specify conditions list must met : conditions specify least one conditions list must met : conditions specify none conditions list must met query can constructed writing list entry , like first example. Alternatively, traktok provides convenience functions build query using query_and, query_or, query_not, make building query little easier. can learn https://developers.tiktok.com/doc/research-api-specs-query-videos#query.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a traktok query — query","text":"","code":"if (FALSE) { # \\dontrun{ # using query directly and supplying the list query(or = list( list( field_name = \"hashtag_name\", operation = \"EQ\", field_values = \"rstats\" ), list( field_name = \"keyword\", operation = \"EQ\", field_values = list(\"rstats\", \"API\") ) )) # starting an empty query and building it up using the query_* functions query() |> query_or(field_name = \"hashtag_name\", operation = \"EQ\", field_values = \"rstats\") |> query_or(field_name = \"keyword\", operation = \"IN\", field_values = c(\"rstats\", \"API\")) } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_comments_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Retrieve video comments — tt_comments_api","text":"","code":"tt_comments_api( video_id, fields = \"all\", start_cursor = 0L, max_pages = 1L, cache = TRUE, verbose = TRUE, token = NULL ) tt_comments( video_id, fields = \"all\", start_cursor = 0L, max_pages = 1L, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_comments_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Retrieve video comments — tt_comments_api","text":"video_id id URL video fields fields returned (defaults ) start_cursor starting cursor, .e., many results skip (picking old search) max_pages results returned batches/pages 100 videos. many requested function stops? cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_comments_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Retrieve video comments — tt_comments_api","text":"data.frame parsed comments","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_comments_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Retrieve video comments — tt_comments_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_comments(\"https://www.tiktok.com/@tiktok/video/7106594312292453675\") # OR tt_comments(\"7106594312292453675\") # OR tt_comments_api(\"7106594312292453675\") } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Get followers and following of a user from the hidden API — tt_get_following_hidden","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"Get 5,000 accounts follow user accounts user follows.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"","code":"tt_get_following_hidden( secuid, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE ) tt_get_follower_hidden( secuid, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE ) tt_get_follower( secuid, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE ) tt_get_following( secuid, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"secuid secuid user. can get tt_videos querying video account. sleep_pool vector numbers waiting period randomly drawn. max_tries often retry request fails. cookiefile path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication. verbose function print status updates screen?","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"data.frame followers","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"","code":"if (FALSE) { # \\dontrun{ df <- tt_user_info_hidden(\"https://www.tiktok.com/@fpoe_at\") tt_get_follower_hidden(df$secUid) } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_json.html","id":null,"dir":"Reference","previous_headings":"","what":"Get json file from a TikTok URL — tt_json","title":"Get json file from a TikTok URL — tt_json","text":"function replaced tt_request_hidden().","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_json.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get json file from a TikTok URL — tt_json","text":"","code":"tt_json(...)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_json.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get json file from a TikTok URL — tt_json","text":"... tt_request_hidden().","code":""},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_playlist_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Lookup TikTok playlist using the research API — tt_playlist_api","text":"","code":"tt_playlist_api(playlist_id, verbose = TRUE, token = NULL)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_playlist_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Lookup TikTok playlist using the research API — tt_playlist_api","text":"playlist_id playlist ID URL playlist. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_playlist_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Lookup TikTok playlist using the research API — tt_playlist_api","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_request_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Get json string from a TikTok URL using the hidden API — tt_request_hidden","title":"Get json string from a TikTok URL using the hidden API — tt_request_hidden","text":"Use function case want check full data given TikTok video account. tt_videos, opinionated selection data included final object. want different information, can use function.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_request_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get json string from a TikTok URL using the hidden API — tt_request_hidden","text":"","code":"tt_request_hidden(url, max_tries = 5L, cookiefile = NULL)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_request_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get json string from a TikTok URL using the hidden API — tt_request_hidden","text":"url URL TikTok video account max_tries often retry request fails. cookiefile path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search.html","id":null,"dir":"Reference","previous_headings":"","what":"Search videos — tt_search","title":"Search videos — tt_search","text":"Searches videos using either Research API (authentication token present, see auth_research) otherwise unofficial hidden API. See tt_search_api tt_search_hidden respectively information functions.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Search videos — tt_search","text":"","code":"tt_search(...)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_search.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Search videos — tt_search","text":"... arguments passed tt_search_api tt_search_hidden. use research API, include token (e.g., token = NULL).","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Search videos — tt_search","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":null,"dir":"Reference","previous_headings":"","what":"Query TikTok videos using the research API — tt_search_api","title":"Query TikTok videos using the research API — tt_search_api","text":"version tt_search explicitly uses Research API. Use tt_search_hidden unofficial API version.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query TikTok videos using the research API — tt_search_api","text":"","code":"tt_search_api( query, start_date = Sys.Date() - 1, end_date = Sys.Date(), fields = \"all\", start_cursor = 0L, search_id = NULL, is_random = FALSE, max_pages = 1, parse = TRUE, cache = TRUE, verbose = TRUE, token = NULL ) tt_query_videos( query, start_date = Sys.Date() - 1, end_date = Sys.Date(), fields = \"all\", start_cursor = 0L, search_id = NULL, is_random = FALSE, max_pages = 1, parse = TRUE, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query TikTok videos using the research API — tt_search_api","text":"query query string object (see query) start_date, end_date start end date narrow search (required). fields fields returned (defaults ) start_cursor starting cursor, .e., many results skip (picking old search) search_id search id (picking old search) is_random Whether query random (defaults FALSE) max_pages results returned batches/pages 100 videos. many requested function stops? parse results parsed? Otherwise, original JSON object returned nested list. cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query TikTok videos using the research API — tt_search_api","text":"data.frame parsed TikTok videos (nested list).","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query TikTok videos using the research API — tt_search_api","text":"","code":"if (FALSE) { # \\dontrun{ # look for a keyword or hashtag by default tt_search_api(\"rstats\") # or build a more elaborate query query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> query_or(field_name = \"hashtag_name\", operation = \"EQ\", # rstats is the only hashtag field_values = \"rstats\") |> query_or(field_name = \"keyword\", operation = \"IN\", # rstats is one of the keywords field_values = \"rstats\") |> query_not(operation = \"EQ\", field_name = \"video_length\", field_values = \"SHORT\") |> tt_search_api() # when a search fails after a while, get the results and pick it back up # (only work with same parameters) last_pull <- last_query() query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> query_or(field_name = \"hashtag_name\", operation = \"EQ\", # rstats is the only hashtag field_values = \"rstats\") |> query_or(field_name = \"keyword\", operation = \"IN\", # rstats is one of the keywords field_values = \"rstats\") |> query_not(operation = \"EQ\", field_name = \"video_length\", field_values = \"SHORT\") |> tt_search_api(start_cursor = length(last_pull) + 1, search_id = attr(last_pull, \"search_id\")) } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Search videos — tt_search_hidden","title":"Search videos — tt_search_hidden","text":"version tt_search explicitly uses unofficial API. Use tt_search_api Research API version.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Search videos — tt_search_hidden","text":"","code":"tt_search_hidden( query, offset = 0, max_pages = Inf, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Search videos — tt_search_hidden","text":"query query one string offset many videos skip. example, already first X search. max_pages many pages get stopping search. sleep_pool vector numbers waiting period randomly drawn. max_tries often retry request fails. cookiefile path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication. verbose function print status updates screen?","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Search videos — tt_search_hidden","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Search videos — tt_search_hidden","text":"function wait scraping two videos make less obvious scraper accessing site. period drawn randomly `sleep_pool` multiplied random fraction.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Search videos — tt_search_hidden","text":"","code":"if (FALSE) { # \\dontrun{ tt_search_hidden(\"#rstats\", max_pages = 2) } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_follower_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get followers and following of users from the research API — tt_user_follower_api","text":"","code":"tt_user_follower_api( username, max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL ) tt_user_following_api( username, max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_follower_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get followers and following of users from the research API — tt_user_follower_api","text":"username name(s) user(s) queried max_pages results returned batches/pages 100 videos. many requested function stops? cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_follower_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get followers and following of users from the research API — tt_user_follower_api","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_follower_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get followers and following of users from the research API — tt_user_follower_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_user_follower_api(\"jbgruber\") # OR tt_user_following_api(\"https://www.tiktok.com/@tiktok\") # OR tt_get_follower(\"https://www.tiktok.com/@tiktok\") } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Lookup TikTok information about a user using the research API — tt_user_info_api","text":"","code":"tt_user_info_api(username, fields = \"all\", verbose = TRUE, token = NULL) tt_user_videos(username, ...) tt_user_info(username, fields = \"all\", verbose = TRUE, token = NULL)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Lookup TikTok information about a user using the research API — tt_user_info_api","text":"username name(s) user(s) queried fields fields returned (defaults ) verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research ) ... additional arguments handed tt_search_api.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Lookup TikTok information about a user using the research API — tt_user_info_api","text":"data.frame parsed TikTok videos user posted","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Lookup TikTok information about a user using the research API — tt_user_info_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_user_info_api(\"jbgruber\") # OR tt_user_info_api(\"https://www.tiktok.com/@tiktok\") # OR tt_user_info(\"https://www.tiktok.com/@tiktok\") } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Get infos about a user from the hidden API — tt_user_info_hidden","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"Get infos user hidden API","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"","code":"tt_user_info_hidden(username, parse = TRUE)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"username URL video username. parse Whether parse data data.frame (set FALSE get full list).","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"data.frame user info.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"","code":"if (FALSE) { # \\dontrun{ df <- tt_user_info_hidden(\"https://www.tiktok.com/@fpoe_at\") } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Lookup which videos were liked by a user using the research API — tt_user_liked_videos_api","text":"","code":"tt_user_liked_videos_api( username, fields = \"all\", max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL ) tt_get_liked( username, fields = \"all\", max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Lookup which videos were liked by a user using the research API — tt_user_liked_videos_api","text":"username name(s) user(s) queried fields fields returned (defaults ) max_pages results returned batches/pages 100 videos. many requested function stops? cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Lookup which videos were liked by a user using the research API — tt_user_liked_videos_api","text":"data.frame parsed TikTok videos user posted","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Lookup which videos were liked by a user using the research API — tt_user_liked_videos_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_user_liked_videos_api(\"jbgruber\") # OR tt_user_liked_videos_api(\"https://www.tiktok.com/@tiktok\") # OR tt_user_liked_videos_api(\"https://www.tiktok.com/@tiktok\") # note: none of these work because nobody has this enabled! } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Get videos from a TikTok user's profile — tt_user_videos_hidden","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"Get videos posted TikTok user.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"","code":"tt_user_videos_hidden( username, solve_captchas = FALSE, return_urls = FALSE, timeout = 5L, verbose = TRUE, ... )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"username username TikTok user whose hidden videos want retrieve. solve_captchas open browser solve appearing captchas manually. return_urls return video URLs instead downloading vidoes. timeout time (seconds) wait scrolling solving captchas. verbose function print status updates screen? ... Additional arguments passed tt_videos_hidden function.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"list video data URLs, depending value return_urls.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"function uses rvest scrape TikTok user's profile retrieve hidden videos.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"","code":"if (FALSE) { # \\dontrun{ # Get hidden videos from the user \"fpoe_at\" tt_user_videos_hidden(\"fpoe_at\") } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"","code":"tt_videos_hidden( video_urls, save_video = TRUE, overwrite = FALSE, dir = \".\", cache_dir = NULL, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE, ... ) tt_videos(...)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"video_urls vector URLs TikTok videos. save_video logical. videos downloaded. overwrite logical. save_video=TRUE file already exists, overwritten? dir directory save videos files . cache_dir set path, one RDS file metadata written disk video. useful many videos want pick left something goes wrong. sleep_pool vector numbers waiting period randomly drawn. max_tries often retry request fails. cookiefile path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication. verbose function print status updates screen? ... handed tt_videos_hidden (tt_videos) () tt_request_hidden.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"function wait scraping two videos make less obvious scraper accessing site. period drawn randomly `sleep_pool` multiplied random fraction. Note video file requested session metadata. URL video file included metadata, link work cases.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"","code":"if (FALSE) { # \\dontrun{ tt_videos(\"https://www.tiktok.com/@tiktok/video/7106594312292453675\") } # }"},{"path":"https://jbgruber.github.io/traktok/news/index.html","id":"traktok-005","dir":"Changelog","previous_headings":"","what":"traktok 0.0.5","title":"traktok 0.0.5","text":"adds experimental tt_user_videos_hidden tt_user_info_hidden rely chromote","code":""}] +[{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"authentication","dir":"Articles","previous_headings":"","what":"Authentication","title":"Research API","text":"get access Research API, need : eligible; create developer account; apply access research API: https://developers.tiktok.com/application/research-api approved client key client secret, can authenticate : recommended run function without arguments, key secret can entered pop mask remain unencrypted R history script. function runs authentication saves resulting token encrypted hard drive. Just run case credentials change.","code":"library(traktok) auth_research()"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"search-videos","dir":"Articles","previous_headings":"Usage","what":"Search Videos","title":"Research API","text":"TikTok uses fine-grained, yet complicated query syntax. convenience, query constructed internally search key phrase directly: match keyword phrase keywords hashtags return 200 results (page 100 results 2 pages requested default) today yesterday. Every whitespace treated operator. extend data range, can set start end (can maximum 30 days apart, limit far can go back): said, query syntax TikTok uses little complicated, can use , boolean operators number fields (\"create_date\", \"username\", \"region_code\", \"video_id\", \"hashtag_name\", \"keyword\", \"music_id\", \"effect_id\", \"video_length\"): make easier use, traktok uses tidyverse style approach building queries. example, get query matches #rstats keywords hashtags, need build query like : #rstats found either hashtag keywords video, video returned. Besides checking EQual, can also use one operations: makes building queries relatively complex, allows fine-grained searches TikTok data: return videos posted US Japan, rstats hashtag one keywords length \"MID\", \"LONG\", \"EXTRA_LONG\".1","code":"tt_query_videos(\"#rstats\", max_pages = 2L) #> ℹ Making initial request ✔ Making initial request [774ms] #> ℹ Parsing data ✔ Parsing data [177ms] #> ── search id: NA ─────────────────────────────────────── #> # A tibble: 0 × 13 #> # ℹ 13 variables: video_id , author_name , #> # view_count , comment_count , #> # share_count , like_count , #> # region_code , create_time , #> # effect_ids , music_id , #> # video_description , hashtag_names , #> # voice_to_text tt_query_videos(\"#rstats\", max_pages = 2L, start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\")) #> ℹ Making initial request ✔ Making initial request [2s] #> ℹ Parsing data ✔ Parsing data [63ms] #> ── search id: 7423432753447932974 ────────────────────── #> # A tibble: 19 × 13 #> video_id author_name view_count comment_count #> #> 1 730689385329705… statistics… 909 4 #> 2 730630774458222… learningca… 1104 11 #> 3 730501447636800… picanumeros 4645 8 #> 4 730297066790799… smooth.lea… 98717 17 #> 5 730247037950160… statistics… 508 0 #> 6 730097749816510… statistics… 27387 1 #> 7 730093147605973… rigochando 2603 4 #> 8 730092229522312… elartedeld… 765 0 #> 9 729998705941704… statistics… 1110 1 #> 10 729965751681473… rigochando 905 4 #> 11 729934294487885… rigochando 555 0 #> 12 729896668413454… rigochando 1312 1 #> 13 729691148659145… biofreelan… 19758 7 #> 14 729691148625178… biofreelan… 5763 1 #> 15 729691147878174… biofreelan… 1019 3 #> 16 729668885660947… mrpecners 657 2 #> 17 729651863537426… l_a_kelly 514 5 #> 18 729649864535081… mrpecners 373 0 #> 19 729628884337898… casaresfel… 274 0 #> # ℹ 9 more variables: share_count , #> # like_count , region_code , #> # create_time , effect_ids , #> # music_id , video_description , #> # hashtag_names , voice_to_text query() |> # start by using query() query_or(field_name = \"hashtag_name\", # add an OR condition on the hashtag field operation = \"IN\", # the value should be IN the list of hashtags field_values = \"rstats\") |> # the hashtag field does not accept the #-symbol query_or(field_name = \"keyword\", # add another OR condition operation = \"IN\", field_values = \"#rstats\") #> S3 #> └─or: #> ├─ #> │ ├─field_name: \"hashtag_name\" #> │ ├─operation: \"IN\" #> │ └─field_values: #> │ └─\"rstats\" #> └─ #> ├─field_name: \"keyword\" #> ├─operation: \"IN\" #> └─field_values: #> └─\"#rstats\" search_df <- query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> query_or(field_name = \"hashtag_name\", operation = \"EQ\", # rstats is the only hashtag field_values = \"rstats\") |> query_or(field_name = \"keyword\", operation = \"IN\", # rstats is one of the keywords field_values = \"rstats\") |> query_not(operation = \"EQ\", field_name = \"video_length\", field_values = \"SHORT\") |> tt_search_api(start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\")) #> ℹ Making initial request ✔ Making initial request [1.1s] #> ℹ Parsing data ✔ Parsing data [59ms] search_df #> ── search id: 7423432753447965742 ────────────────────── #> # A tibble: 2 × 13 #> video_id author_name view_count comment_count #> #> 1 7296688856609475… mrpecners 657 2 #> 2 7296498645350812… mrpecners 373 0 #> # ℹ 9 more variables: share_count , #> # like_count , region_code , #> # create_time , effect_ids , #> # music_id , video_description , #> # hashtag_names , voice_to_text "},{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"get-user-information","dir":"Articles","previous_headings":"Usage","what":"Get User Information","title":"Research API","text":"really much getting basic user info, can : wish return videos user, can use search : can also find videos user pinned top page: find user liked, can use: Note, making likes public opt-feature TikTok almost nobody enabled, give lot warning… can usually get information user follows: followed :","code":"tt_user_info_api(username = c(\"tiktok\", \"https://www.tiktok.com/@statisticsglobe\")) #> ℹ Getting user tiktok ✔ Got user tiktok [508ms] #> ℹ Getting user statisticsglobe ✔ Got user statisticsglobe [518ms] #> # A tibble: 2 × 8 #> is_verified likes_count video_count avatar_url #> #> 1 TRUE 330919903 1073 https://p16-pu-si… #> 2 FALSE 1660 92 https://p16-sign-… #> # ℹ 4 more variables: bio_description , #> # display_name , follower_count , #> # following_count query() |> query_and(field_name = \"username\", operation = \"EQ\", field_values = \"statisticsglobe\") |> tt_search_api(start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\")) #> ℹ Making initial request ✔ Making initial request [872ms] #> ℹ Parsing data ✔ Parsing data [65ms] #> ── search id: 7423432753448064046 ────────────────────── #> # A tibble: 5 × 13 #> video_id author_name view_count comment_count #> #> 1 7306893853297052… statistics… 909 4 #> 2 7302470379501604… statistics… 508 0 #> 3 7300977498165103… statistics… 27387 1 #> 4 7299987059417042… statistics… 1110 1 #> 5 7297389484524506… statistics… 538 2 #> # ℹ 9 more variables: share_count , #> # like_count , region_code , #> # create_time , effect_ids , #> # music_id , video_description , #> # hashtag_names , voice_to_text tt_user_pinned_videos_api(c(\"tiktok\", \"https://www.tiktok.com/@smooth.learning.c\")) #> ℹ Getting user tiktok ✖ Getting user tiktok [367ms] #> ℹ Getting user smooth.learning.c ✔ Got user smooth.learning.c [571ms] #> # A tibble: 1 × 14 #> pinned_by_user create_time id is_stem_verified #> #> 1 smooth.learning.c 1690255097 725959… FALSE #> # ℹ 10 more variables: region_code , #> # video_duration , view_count , #> # video_description , comment_count , #> # hashtag_names , like_count , #> # music_id , share_count , username tt_get_liked(\"jbgruber\") #> ℹ Getting user jbgruber ✔ Got user jbgruber [1.5s] #> # A tibble: 98 × 14 #> id username create_time video_description #> #> 1 7355902326877… america… 1712679503 \"Stitch with @Mr… #> 2 7268078476102… carterp… 1692231398 \"Are you going t… #> 3 7419692903460… okbrune… 1727531892 \"Die ganze Wahrh… #> 4 7405633113835… funny_s… 1724258332 \"#fyp #fypシ #fu… #> 5 7398532172048… lib0160… 1722605019 \"Me and ChatGPT … #> 6 7364763547038… vquasch… 1714742648 \"Einige Medien u… #> 7 7346577913858… ct_3003 1710508473 \"Diese Platine f… #> 8 7379856141972… lizthed… 1718256663 \"Replying to @Ar… #> 9 7415189182865… felixba… 1726483284 \"Es geht wieder … #> 10 7422673042553… grueneb… 1728225752 \"Was Söder uns e… #> # ℹ 88 more rows #> # ℹ 10 more variables: region_code , #> # video_duration , view_count , #> # like_count , comment_count , #> # share_count , music_id , #> # hashtag_names , is_stem_verified , #> # liked_by_user tt_user_following_api(username = \"jbgruber\") #> ℹ Getting user jbgruber ✔ Got user jbgruber [296ms] #> # A tibble: 19 × 3 #> display_name username following_user #> #> 1 SohoBrody rudeboybrody jbgruber #> 2 Last Week Tonight lastweektonight… jbgruber #> 3 schlantologie schlantologie jbgruber #> 4 Alex Falcone alex_falcone jbgruber #> 5 dadNRG dadnrg jbgruber #> 6 Einfach Genial Tictok user22690086508… jbgruber #> 7 noir_concrete_studio noir_concrete_s… jbgruber #> 8 fatDumbledore fatdumbledore13… jbgruber #> 9 fragdenstaat.de fragdenstaat.de jbgruber #> 10 Erikadbka erikadbka jbgruber #> 11 BÜNDNIS 90/DIE GRÜNEN diegruenen jbgruber #> 12 lagedernationclips lagedernationcl… jbgruber #> 13 Alexandra Ils kitty.fantastico jbgruber #> 14 future infinitive ☸️ lizthedeveloper jbgruber #> 15 Tim Achtermeyer achtermeyer jbgruber #> 16 Jay Foreman jayforeman jbgruber #> 17 Cosmo whereiswanda jbgruber #> 18 Tim Walz timwalz jbgruber #> 19 Shahak Shapira shahakshapira jbgruber tt_user_follower_api(\"https://www.tiktok.com/@tiktok\") #> ℹ Getting user tiktok ✔ Got user tiktok [442ms] #> # A tibble: 90 × 3 #> username display_name following_user #> #> 1 galbruwt reeyyp tiktok #> 2 user5235623178011 👑কিং রানা 🥀 tiktok #> 3 rokyevay07 👑Rokye Vay👑 tiktok #> 4 babyylious08 babyylious08 tiktok #> 5 user8283823357 hd❤️‍🩹jaan❤️‍🩹hi❤️‍🩹❤️ tiktok #> 6 user45628309141722 سامي tiktok #> 7 nu.th085 Nâu Thị tiktok #> 8 halimeysll halimeysll tiktok #> 9 taru.tristiyanto Taru Tristiyanto tiktok #> 10 vng.lan.hng09 Vương Lan Hường tiktok #> # ℹ 80 more rows"},{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"obtain-all-comments-of-a-video","dir":"Articles","previous_headings":"Usage","what":"Obtain all Comments of a Video","title":"Research API","text":", much talk comes comments API. need supply video ID, either already: got search: let function extract URL video: essentially . Note, find functionality Research API lacking, nothing keeps using unofficial API functions.","code":"tt_comments_api(video_id = \"7302470379501604128\") #> ℹ Making initial request ✔ Making initial request [4.9s] #> ℹ Parsing data ✔ Parsing data [68ms] #> ── search id: ───────────────────────────────────────── #> # A tibble: 1 × 7 #> create_time id like_count parent_comment_id #> #> 1 1700243424 730248974199… 0 7302470379501604… #> # ℹ 3 more variables: reply_count , text , #> # video_id tt_comments_api(video_id = search_df$video_id[1]) #> ℹ Making initial request ✔ Making initial request [4.8s] #> ℹ Parsing data ✔ Parsing data [61ms] #> ── search id: ───────────────────────────────────────── #> # A tibble: 2 × 7 #> create_time id like_count parent_comment_id #> #> 1 1698893206 729669068138… 1 7296688856609475… #> 2 1698893251 729669083429… 0 7296690681388204… #> # ℹ 3 more variables: reply_count , text , #> # video_id tt_comments_api(video_id = \"https://www.tiktok.com/@nicksinghtech/video/7195762648716152107?q=%23rstats\") #> ℹ Making initial request ✔ Making initial request [5.9s] #> ℹ Parsing data ✔ Parsing data [58ms] #> ── search id: ───────────────────────────────────────── #> # A tibble: 96 × 7 #> text video_id create_time id like_count #> #> 1 You gotta know… 7195762… 1675394834 7195… 314 #> 2 R is the goat … 7195762… 1675457114 7196… 232 #> 3 Ppl who like E… 7195762… 1675458796 7196… 177 #> 4 Fair but doesn… 7195762… 1675395061 7195… 166 #> 5 babe RStudio i… 7195762… 1675624739 7196… 71 #> 6 Excel is the b… 7195762… 1675465779 7196… 71 #> 7 NOT THE SAS SL… 7195762… 1675494738 7196… 27 #> 8 I won't take t… 7195762… 1675691471 7197… 17 #> 9 No love for ST… 7195762… 1675656122 7196… 16 #> 10 I use SAS 🫡 7195762… 1675440749 7195… 16 #> # ℹ 86 more rows #> # ℹ 2 more variables: parent_comment_id , #> # reply_count "},{"path":"https://jbgruber.github.io/traktok/articles/research-api.html","id":"dealing-with-rate-limits-and-continuing-old-searches","dir":"Articles","previous_headings":"","what":"Dealing with rate limits and continuing old searches","title":"Research API","text":"moment writing vignette, TikTok rate limits Research API follows: Currently, daily limit set 1000 requests per day, allowing obtain 100,000 records per day across APIs. (Video Comments API can return 100 records per request). daily quota gets reset 12 UTC. [Source] Depending like , might enough . case, can actually save search pick back reset. facilitate , search result objects contain two extra pieces information attributes: want continue search, whether rate limit decided want results, can providing search_id cursor tt_search_api. search cut short rate limit another issue, can retrieve results already received search_df <- last_query(). search_df cases contain relevant search_id cursor attributes: Note cursor equal many videos got , API also counts videos “deleted/marked private users etc.” [See max_count Query Videos].","code":"search_df <- query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> tt_search_api(start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\"), max_pages = 1) #> ℹ Making initial request ✔ Making initial request [2.4s] #> ℹ Parsing data ✔ Parsing data [71ms] attr(search_df, \"search_id\") #> [1] \"7423432753448096814\" attr(search_df, \"cursor\") #> [1] 100 search_df2 <- query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> tt_search_api(start_date = as.Date(\"2023-11-01\"), end_date = as.Date(\"2023-11-29\"), # this part is new start_cursor = attr(search_df, \"cursor\"), search_id = attr(search_df, \"search_id\"), #### max_pages = 1) #> ℹ Making initial request ✔ Making initial request [5.1s] #> ℹ Parsing data ✔ Parsing data [21ms] attr(search_df2, \"search_id\") #> [1] \"7336340473470063662\" attr(search_df2, \"cursor\") #> [1] 200"},{"path":"https://jbgruber.github.io/traktok/articles/unofficial-api.html","id":"authentication","dir":"Articles","previous_headings":"","what":"Authentication","title":"Unofficial API","text":"easiest way get cookies needed authentication export necessary cookies browser using browser extension (logging TikTok.com least ). can recommend “Get cookies.txt” Chromium based browsers “cookies.txt” Firefox (note almost browsers used today based one ). Save cookies.txt file, look something like : matter download cookies just ones specific TikTok, use cookiemonster package deal . read cookies specific encrypted file, simply use: ’s ! traktok access cookies whenever necessary.","code":"# Netscape HTTP Cookie File # https://curl.haxx.se/rfc/cookie_spec.html # This is a generated file! Do not edit. .tiktok.com TRUE / TRUE 1728810805 cookie-consent {%22ga%22:true%2C%22af%... .tiktok.com TRUE / TRUE 1700471788 passport_csrf_token e07d3487c11ce5258a3... .tiktok.com TRUE / FALSE 1700471788 passport_csrf_token_default e07d3487c11... #HttpOnly_.tiktok.com TRUE / TRUE 1700493610 multi_sids 71573310862246389... #HttpOnly_.tiktok.com TRUE / TRUE 1700493610 cmpl_token AgQQAPORF-RO0rNtH... ... cookiemonster::add_cookies(\"tiktok.com_cookies.txt\")"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/articles/unofficial-api.html","id":"search-videos","dir":"Articles","previous_headings":"Usage","what":"Search videos","title":"Unofficial API","text":"search videos, can use either tt_search tt_search_hidden, , long token Research API. get first two pages search results (one page 12 videos), can use command: already gives pretty much information want videos found.","code":"rstats_df <- tt_search_hidden(\"#rstats\", max_pages = 2) #> ℹ Getting page 1 ⏲ waiting 0.5 seconds ℹ Getting page 1 ✔ Got page 1. Found 12 videos. [1.9s] #> ℹ Getting page 2 ✔ Got page 2. Found 12 videos. [690ms] rstats_df #> # A tibble: 24 × 20 #> video_id video_timestamp video_url video_length video_title #> #> 1 71151144… 2022-06-30 19:17:53 https://… 135 \"R for Beg… #> 2 72522261… 2023-07-05 07:01:45 https://… 36 \"Wow!!! TH… #> 3 72420686… 2023-06-07 22:05:16 https://… 34 \"R GRAPHIC… #> 4 72134135… 2023-03-22 16:49:12 https://… 6 \"R and me … #> 5 72576898… 2023-07-20 00:23:40 https://… 56 \"Pie chart… #> 6 72999870… 2023-11-10 23:58:21 https://… 51 \"Quick R Q… #> 7 72783048… 2023-09-13 13:40:21 https://… 36 \"Quick R Q… #> 8 73029706… 2023-11-19 00:56:09 https://… 163 \"What is c… #> 9 71670108… 2022-11-17 15:42:56 https://… 58 \"Here’s an… #> 10 72933174… 2023-10-24 00:36:48 https://… 9 \"#CapCut #… #> # ℹ 14 more rows #> # ℹ 15 more variables: video_diggcount , #> # video_sharecount , video_commentcount , #> # video_playcount , video_is_ad , author_name , #> # author_nickname , author_followercount , #> # author_followingcount , author_heartcount , #> # author_videocount , author_diggcount , …"},{"path":"https://jbgruber.github.io/traktok/articles/unofficial-api.html","id":"get-metadata-and-download-videos","dir":"Articles","previous_headings":"Usage","what":"Get metadata and download videos","title":"Unofficial API","text":"However, can obtain information, importantly video file, using tt_videos: Per default, function waits one ten seconds (chosen random) making two calls, make obvious data scraped TikTok. can speed process (risk), changing sleep_pool argument, controls minimum maximum number seconds wait: scraping lot URLs, function might fail eventually, due poor connection TikTok blocking requests. therefore usually makes sense save progress cache directory: Note video files downloaded dir directory (working directory default), independently cache directory. information feel missing data.frame tt_videos returns, can look raw, unparsed json data using: Parsing result list using fromJSON, results rather complex nested list. can look see data interested ","code":"rstats_df2 <- tt_videos(rstats_df$video_url[1:2], save_video = TRUE) #> ℹ Getting video 7115114419314560298 ⏲ waiting 0.2 seconds ℹ Getting video 7115114419314560298 ✔ Got video 7115114419314560298 (1/2). File size: 2.5 Mb. [2.5s] #> ℹ Getting video 7252226153828584731 ✔ Got video 7252226153828584731 (2/2). File size: 1.7 Mb. [999ms] rstats_df2 #> # A tibble: 2 × 19 #> video_id video_url video_timestamp video_length video_title #> #> 1 711511441… https://… 2022-06-30 19:17:53 135 R for Begi… #> 2 725222615… https://… 2023-07-05 07:01:45 36 Wow!!! THI… #> # ℹ 14 more variables: video_locationcreated , #> # video_diggcount , video_sharecount , #> # video_commentcount , video_playcount , #> # author_username , author_nickname , #> # author_bio , download_url , html_status , #> # music , challenges , is_classified , #> # video_fn rstats_df3 <- tt_videos(rstats_df$video_url[3:4], save_video = TRUE, sleep_pool = 0.1) #> ℹ Getting video 7242068680484408581 ⏲ waiting 0.1 seconds ℹ Getting video 7242068680484408581 ✔ Got video 7242068680484408581 (1/2). File size: 1.8 Mb. [2.6s] #> ℹ Getting video 7213413598998056234 ✔ Got video 7213413598998056234 (2/2). File size: 598.1 Kb. [1.7s] rstats_df3 #> # A tibble: 2 × 19 #> video_id video_url video_timestamp video_length video_title #> #> 1 724206868… https://… 2023-06-07 22:05:16 34 \"R GRAPHIC… #> 2 721341359… https://… 2023-03-22 16:49:12 6 \"R and me … #> # ℹ 14 more variables: video_locationcreated , #> # video_diggcount , video_sharecount , #> # video_commentcount , video_playcount , #> # author_username , author_nickname , #> # author_bio , download_url , html_status , #> # music , challenges , is_classified , #> # video_fn rstats_df3 <- tt_videos(rstats_df$video_url[5:6], cache_dir = \"rstats\") #> ℹ Getting video 7257689890245201153 ⏲ waiting 1.7 seconds ℹ Getting video 7257689890245201153 ✔ Got video 7257689890245201153 (1/2). File size: 1.7 Mb. [2.6s] #> ℹ Getting video 7299987059417042209 ✔ Got video 7299987059417042209 (2/2). File size: 1.2 Mb. [1.8s] list.files(\"rstats\") #> [1] \"7257689890245201153.json\" \"7299987059417042209.json\" rstats_list1 <- tt_request_hidden(rstats_df$video_url[1]) |> jsonlite::fromJSON()"},{"path":"https://jbgruber.github.io/traktok/articles/unofficial-api.html","id":"get-followers-and-who-a-user-is-following","dir":"Articles","previous_headings":"Usage","what":"Get followers and who a user is following","title":"Unofficial API","text":"Getting followers user following (moment?) little tricky use, since TikTok blocks requests users profile page anti-scraping measures. circumvent , can open users page browser right-click show source code:1 can search copy authorSecId value: authorSecId can look maximum 5,000 followers per account: Likewise, can also check account follows:","code":"tt_get_follower(secuid = \"MS4wLjABAAAAwiH32UMb5RenqEN7duyfLIeGQgSIx9WtgtOILt55q6ueUXgz4gHqZC5HFx4nabPi\", verbose = FALSE) #> #> # A tibble: 1,116 × 27 #> avatarLarger avatarMedium avatarThumb commentSetting #> #> 1 https://p16-sign-sg.tik… https://p16… https://p1… 0 #> 2 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 3 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 4 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 5 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 6 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 7 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 8 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 9 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 10 https://p16-sign-va.tik… https://p16… https://p1… 0 #> # ℹ 1,106 more rows #> # ℹ 23 more variables: downloadSetting , duetSetting , #> # ftc , id , isADVirtual , nickname , #> # openFavorite , privateAccount , relation , #> # secUid , secret , signature , #> # stitchSetting , ttSeller , uniqueId , #> # verified , diggCount , followerCount , … tt_get_following(secuid = \"MS4wLjABAAAAwiH32UMb5RenqEN7duyfLIeGQgSIx9WtgtOILt55q6ueUXgz4gHqZC5HFx4nabPi\", verbose = FALSE) #> #> # A tibble: 489 × 28 #> avatarLarger avatarMedium avatarThumb commentSetting #> #> 1 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 2 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 3 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 4 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 5 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 6 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 7 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 8 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 9 https://p16-sign-va.tik… https://p16… https://p1… 0 #> 10 https://p16-sign-va.tik… https://p16… https://p1… 0 #> # ℹ 479 more rows #> # ℹ 24 more variables: downloadSetting , duetSetting , #> # ftc , id , isADVirtual , nickname , #> # openFavorite , privateAccount , relation , #> # secUid , secret , signature , #> # stitchSetting , ttSeller , uniqueId , #> # verified , diggCount , followerCount , … list.files(pattern = \".mp4\") |> unlink() unlink(\"rstats\", recursive = TRUE)"},{"path":"https://jbgruber.github.io/traktok/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Johannes B. Gruber. Author, maintainer.","code":""},{"path":"https://jbgruber.github.io/traktok/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Gruber, Johannes B. (2023). traktok. R package scrape data TikTok. R package version 0.0.4.9000. https://github.com/JBGruber/traktok.","code":"@Manual{, title = {traktok. Getting TikTok data through the official and unofficial APIs}, author = {Johannes B. Gruber}, year = {2023}, url = {https://github.com/JBGruber/traktok}, note = {R package version 0.0.4.9000}, }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/index.html","id":"feature-overview","dir":"","previous_headings":"","what":"Feature overview","title":"Collecting TikTok Data","text":"goal traktok provide easy access TikTok data. package one started R port Deen Freelon’s Pyktok Python module (though complete rewrite without Python dependencies). now covers functions secret hidden API TikTok using show/search/play videos Website official Research API. Since Research API misses important features (since everyone access ) can often make sense still use hidden API mocks requests browser. However, important disclaimer hidden API applies: program may stop working suddenly TikTok changes stores data (see Freelon, 2018). However, last times, fixed rather quickly (e.g., #12).","code":""},{"path":"https://jbgruber.github.io/traktok/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Collecting TikTok Data","text":"can install development version traktok GitHub :","code":"# install.packages(\"remotes\") remotes::install_github(\"JBGruber/traktok\")"},{"path":"https://jbgruber.github.io/traktok/index.html","id":"in-research","dir":"","previous_headings":"","what":"In Research","title":"Collecting TikTok Data","text":"research papers projects used traktok gather data: Hohner, J., Kakavand, ., & Rothut, S. (2024). Analyzing Radical Visuals Scale: Far-Right Groups Mobilize TikTok. Journal Digital Social Research, 6(1), 10–30. https://doi.org/10.33621/jdsr.v6i1.200 Bach, P., Gitomer, ., Devries, M., Walker, C., Deyoe, D., Atienza-Bathelemy, J., Foucault Welles, B., Freelon, D., & Zulli, D. (2023, October). Stitching Politics Identity TikTok. Panel presented AoIR2023: 24th Annual Conference Association Internet Researchers. Philadelphia, PA, USA: AoIR. Retrieved http://spir.aoir.org Wirz, D. S., Zai, F., Vogler, D., Urman, ., & Eisenegger, M. (2023). Die Qualität von Schweizer Medien auf Instagram und TikTok. https://doi.org/10.5167/UZH-238605 Giglietto, F. (2024). Dashboard: TikTok Coordinated Sharing Network. https://fabiogiglietto.github.io/tiktok_csbn/tt_viz.html used traktok research paper project, please extend list Pull Request create issue","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":null,"dir":"Reference","previous_headings":"","what":"Check whether you are authenticated — auth_check","title":"Check whether you are authenticated — auth_check","text":"Check necessary token cookies stored computer already. default, function checks authentication research hidden API. learn can authenticate, look vignette research (vignette(\"research-api\", package = \"traktok\")) hidden (vignette(\"unofficial-api\", package = \"traktok\")) API.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Check whether you are authenticated — auth_check","text":"","code":"auth_check(research = TRUE, hidden = TRUE, silent = FALSE)"},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Check whether you are authenticated — auth_check","text":"research, hidden turn check /research hidden API. silent return check(s) successful, status screen","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Check whether you are authenticated — auth_check","text":"logical vector (invisible)","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_check.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Check whether you are authenticated — auth_check","text":"","code":"auth_check() #> Error in cookiemonster::get_cookies(\"^(www.)*tiktok.com\") : #> The directory ~/.cache/r_cookies does not contain any cookies yet. Use #> `add_cookies()` to store cookies for a website (see `vignette(\"cookies\", #> \"cookiemonster\")` for details)."},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Authenticate for the hidden/unofficial API — auth_hidden","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"Guides authentication hidden/unofficial API#'","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"","code":"auth_hidden(cookiefile, live = interactive())"},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"cookiefile optional path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication. live opens Chromium browser guide auth process.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"nothing. Called set authentication","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Authenticate for the hidden/unofficial API — auth_hidden","text":"","code":"if (FALSE) { # \\dontrun{ # to run through the steps of authentication auth_hidden() # or point to a cookie file directly auth_hidden(\"www.tiktok.com_cookies.txt\") } # }"},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":null,"dir":"Reference","previous_headings":"","what":"Authenticate for the official research API — auth_research","title":"Authenticate for the official research API — auth_research","text":"Authenticate official research API","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Authenticate for the official research API — auth_research","text":"","code":"auth_research(client_key, client_secret)"},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Authenticate for the official research API — auth_research","text":"client_key Client key authentication client_secret Client secret authentication","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Authenticate for the official research API — auth_research","text":"authentication token","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Authenticate for the official research API — auth_research","text":"need apply access API get key secret TikTok. See https://developers.tiktok.com/products/research-api/ information.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/auth_research.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Authenticate for the official research API — auth_research","text":"","code":"if (FALSE) { # \\dontrun{ auth_research(client_key, client_secret) } # }"},{"path":"https://jbgruber.github.io/traktok/reference/last_query.html","id":null,"dir":"Reference","previous_headings":"","what":"Retrieve most recent query — last_query","title":"Retrieve most recent query — last_query","text":"tt_search_api tt_comments_api fail already getting several pages, can use function get videos retrieved far memory. work session crashed. case, look tempdir() RDS file last resort.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/last_query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Retrieve most recent query — last_query","text":"","code":"last_query() last_comments()"},{"path":"https://jbgruber.github.io/traktok/reference/last_query.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Retrieve most recent query — last_query","text":"list unparsed videos","code":""},{"path":"https://jbgruber.github.io/traktok/reference/print.traktok_query.html","id":null,"dir":"Reference","previous_headings":"","what":"Print a traktok query — print.traktok_query","title":"Print a traktok query — print.traktok_query","text":"Print traktok query tree","code":""},{"path":"https://jbgruber.github.io/traktok/reference/print.traktok_query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Print a traktok query — print.traktok_query","text":"","code":"# S3 method for class 'traktok_query' print(x, ...)"},{"path":"https://jbgruber.github.io/traktok/reference/print.traktok_query.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Print a traktok query — print.traktok_query","text":"x object class traktok_query ... Additional arguments passed lobstr::tree","code":""},{"path":"https://jbgruber.github.io/traktok/reference/print.traktok_query.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Print a traktok query — print.traktok_query","text":"","code":"query() |> query_and(field_name = \"hashtag_name\", operation = \"EQ\", field_values = \"rstats\") |> print() #> S3 #> └─and: #> └─ #> ├─field_name: \"hashtag_name\" #> ├─operation: \"EQ\" #> └─field_values: #> └─\"rstats\""},{"path":"https://jbgruber.github.io/traktok/reference/print.tt_results.html","id":null,"dir":"Reference","previous_headings":"","what":"Print search result — print.tt_results","title":"Print search result — print.tt_results","text":"Print traktok search results","code":""},{"path":"https://jbgruber.github.io/traktok/reference/print.tt_results.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Print search result — print.tt_results","text":"","code":"# S3 method for class 'tt_results' print(x, ...)"},{"path":"https://jbgruber.github.io/traktok/reference/print.tt_results.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Print search result — print.tt_results","text":"x object class tt_results ... used.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a traktok query — query","title":"Create a traktok query — query","text":"Create traktok query given parameters.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a traktok query — query","text":"","code":"query(and = NULL, or = NULL, not = NULL) query_and(q, field_name, operation, field_values) query_or(q, field_name, operation, field_values) query_not(q, field_name, operation, field_values)"},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a traktok query — query","text":", , list //conditions. Must contain one multiple lists field_name, operation, field_values (see example). q traktok query created query. field_name field name query . One : \"create_date\", \"username\", \"region_code\", \"video_id\", \"hashtag_name\", \"keyword\", \"music_id\", \"effect_id\", \"video_length\". operation One : \"EQ\", \"\", \"GT\", \"GTE\", \"LT\", \"LTE\". field_values vector values search .","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a traktok query — query","text":"traktok query.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Create a traktok query — query","text":"TikTok's query consists rather complicated lists dividing query elements , : : conditions specify conditions list must met : conditions specify least one conditions list must met : conditions specify none conditions list must met query can constructed writing list entry , like first example. Alternatively, traktok provides convenience functions build query using query_and, query_or, query_not, make building query little easier. can learn https://developers.tiktok.com/doc/research-api-specs-query-videos#query.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/query.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a traktok query — query","text":"","code":"if (FALSE) { # \\dontrun{ # using query directly and supplying the list query(or = list( list( field_name = \"hashtag_name\", operation = \"EQ\", field_values = \"rstats\" ), list( field_name = \"keyword\", operation = \"EQ\", field_values = list(\"rstats\", \"API\") ) )) # starting an empty query and building it up using the query_* functions query() |> query_or(field_name = \"hashtag_name\", operation = \"EQ\", field_values = \"rstats\") |> query_or(field_name = \"keyword\", operation = \"IN\", field_values = c(\"rstats\", \"API\")) } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_comments_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Retrieve video comments — tt_comments_api","text":"","code":"tt_comments_api( video_id, fields = \"all\", start_cursor = 0L, max_pages = 1L, cache = TRUE, verbose = TRUE, token = NULL ) tt_comments( video_id, fields = \"all\", start_cursor = 0L, max_pages = 1L, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_comments_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Retrieve video comments — tt_comments_api","text":"video_id id URL video fields fields returned (defaults ) start_cursor starting cursor, .e., many results skip (picking old search) max_pages results returned batches/pages 100 videos. many requested function stops? cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_comments_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Retrieve video comments — tt_comments_api","text":"data.frame parsed comments","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_comments_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Retrieve video comments — tt_comments_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_comments(\"https://www.tiktok.com/@tiktok/video/7106594312292453675\") # OR tt_comments(\"7106594312292453675\") # OR tt_comments_api(\"7106594312292453675\") } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_follower.html","id":null,"dir":"Reference","previous_headings":"","what":"Get followers and following of users — tt_get_follower","title":"Get followers and following of users — tt_get_follower","text":"Get usernames users follows user (tt_get_follower) get user following (tt_get_following).","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_follower.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get followers and following of users — tt_get_follower","text":"","code":"tt_get_follower(...) tt_get_following(...)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_follower.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get followers and following of users — tt_get_follower","text":"... arguments passed tt_user_follower_api tt_get_follower_hidden. use research API, include token (e.g., token = NULL).","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_follower.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get followers and following of users — tt_get_follower","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Get followers and following of a user from the hidden API — tt_get_following_hidden","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"Get 5,000 accounts follow user accounts user follows.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"","code":"tt_get_following_hidden( secuid, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE ) tt_get_follower_hidden( secuid, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"secuid secuid user. can get tt_videos querying video account. sleep_pool vector numbers waiting period randomly drawn. max_tries often retry request fails. cookiefile path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication. verbose function print status updates screen?","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"data.frame followers","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get followers and following of a user from the hidden API — tt_get_following_hidden","text":"","code":"if (FALSE) { # \\dontrun{ df <- tt_user_info_hidden(\"https://www.tiktok.com/@fpoe_at\") tt_get_follower_hidden(df$secUid) } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_json.html","id":null,"dir":"Reference","previous_headings":"","what":"Get json file from a TikTok URL — tt_json","title":"Get json file from a TikTok URL — tt_json","text":"function replaced tt_request_hidden().","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_json.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get json file from a TikTok URL — tt_json","text":"","code":"tt_json(...)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_json.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get json file from a TikTok URL — tt_json","text":"... tt_request_hidden().","code":""},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_playlist_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Lookup TikTok playlist using the research API — tt_playlist_api","text":"","code":"tt_playlist_api(playlist_id, verbose = TRUE, token = NULL) tt_playlist(playlist_id, verbose = TRUE, token = NULL)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_playlist_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Lookup TikTok playlist using the research API — tt_playlist_api","text":"playlist_id playlist ID URL playlist. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_playlist_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Lookup TikTok playlist using the research API — tt_playlist_api","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_request_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Get json string from a TikTok URL using the hidden API — tt_request_hidden","title":"Get json string from a TikTok URL using the hidden API — tt_request_hidden","text":"Use function case want check full data given TikTok video account. tt_videos, opinionated selection data included final object. want different information, can use function.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_request_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get json string from a TikTok URL using the hidden API — tt_request_hidden","text":"","code":"tt_request_hidden(url, max_tries = 5L, cookiefile = NULL)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_request_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get json string from a TikTok URL using the hidden API — tt_request_hidden","text":"url URL TikTok video account max_tries often retry request fails. cookiefile path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search.html","id":null,"dir":"Reference","previous_headings":"","what":"Search videos — tt_search","title":"Search videos — tt_search","text":"Searches videos using either Research API (authentication token present, see auth_research) otherwise unofficial hidden API. See tt_search_api tt_search_hidden respectively information functions.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Search videos — tt_search","text":"","code":"tt_search(...)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_search.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Search videos — tt_search","text":"... arguments passed tt_search_api tt_search_hidden. use research API, include token (e.g., token = NULL).","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Search videos — tt_search","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":null,"dir":"Reference","previous_headings":"","what":"Query TikTok videos using the research API — tt_search_api","title":"Query TikTok videos using the research API — tt_search_api","text":"version tt_search explicitly uses Research API. Use tt_search_hidden unofficial API version.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query TikTok videos using the research API — tt_search_api","text":"","code":"tt_search_api( query, start_date = Sys.Date() - 1, end_date = Sys.Date(), fields = \"all\", start_cursor = 0L, search_id = NULL, is_random = FALSE, max_pages = 1, parse = TRUE, cache = TRUE, verbose = TRUE, token = NULL ) tt_query_videos( query, start_date = Sys.Date() - 1, end_date = Sys.Date(), fields = \"all\", start_cursor = 0L, search_id = NULL, is_random = FALSE, max_pages = 1, parse = TRUE, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query TikTok videos using the research API — tt_search_api","text":"query query string object (see query) start_date, end_date start end date narrow search (required). fields fields returned (defaults ) start_cursor starting cursor, .e., many results skip (picking old search) search_id search id (picking old search) is_random Whether query random (defaults FALSE) max_pages results returned batches/pages 100 videos. many requested function stops? parse results parsed? Otherwise, original JSON object returned nested list. cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query TikTok videos using the research API — tt_search_api","text":"data.frame parsed TikTok videos (nested list).","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query TikTok videos using the research API — tt_search_api","text":"","code":"if (FALSE) { # \\dontrun{ # look for a keyword or hashtag by default tt_search_api(\"rstats\") # or build a more elaborate query query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> query_or(field_name = \"hashtag_name\", operation = \"EQ\", # rstats is the only hashtag field_values = \"rstats\") |> query_or(field_name = \"keyword\", operation = \"IN\", # rstats is one of the keywords field_values = \"rstats\") |> query_not(operation = \"EQ\", field_name = \"video_length\", field_values = \"SHORT\") |> tt_search_api() # when a search fails after a while, get the results and pick it back up # (only work with same parameters) last_pull <- last_query() query() |> query_and(field_name = \"region_code\", operation = \"IN\", field_values = c(\"JP\", \"US\")) |> query_or(field_name = \"hashtag_name\", operation = \"EQ\", # rstats is the only hashtag field_values = \"rstats\") |> query_or(field_name = \"keyword\", operation = \"IN\", # rstats is one of the keywords field_values = \"rstats\") |> query_not(operation = \"EQ\", field_name = \"video_length\", field_values = \"SHORT\") |> tt_search_api(start_cursor = length(last_pull) + 1, search_id = attr(last_pull, \"search_id\")) } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Search videos — tt_search_hidden","title":"Search videos — tt_search_hidden","text":"version tt_search explicitly uses unofficial API. Use tt_search_api Research API version.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Search videos — tt_search_hidden","text":"","code":"tt_search_hidden( query, offset = 0, max_pages = Inf, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Search videos — tt_search_hidden","text":"query query one string offset many videos skip. example, already first X search. max_pages many pages get stopping search. sleep_pool vector numbers waiting period randomly drawn. max_tries often retry request fails. cookiefile path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication. verbose function print status updates screen?","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Search videos — tt_search_hidden","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Search videos — tt_search_hidden","text":"function wait scraping two videos make less obvious scraper accessing site. period drawn randomly `sleep_pool` multiplied random fraction.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_search_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Search videos — tt_search_hidden","text":"","code":"if (FALSE) { # \\dontrun{ tt_search_hidden(\"#rstats\", max_pages = 2) } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_follower_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get followers and following of users from the research API — tt_user_follower_api","text":"","code":"tt_user_follower_api( username, max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL ) tt_user_following_api( username, max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_follower_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get followers and following of users from the research API — tt_user_follower_api","text":"username name(s) user(s) queried max_pages results returned batches/pages 100 videos. many requested function stops? cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_follower_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get followers and following of users from the research API — tt_user_follower_api","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_follower_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get followers and following of users from the research API — tt_user_follower_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_user_follower_api(\"jbgruber\") # OR tt_user_following_api(\"https://www.tiktok.com/@tiktok\") # OR tt_get_follower(\"https://www.tiktok.com/@tiktok\") } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Lookup TikTok information about a user using the research API — tt_user_info_api","text":"","code":"tt_user_info_api(username, fields = \"all\", verbose = TRUE, token = NULL) tt_user_videos(username, ...) tt_user_info(username, fields = \"all\", verbose = TRUE, token = NULL)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Lookup TikTok information about a user using the research API — tt_user_info_api","text":"username name(s) user(s) queried fields fields returned (defaults ) verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research ) ... additional arguments handed tt_search_api.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Lookup TikTok information about a user using the research API — tt_user_info_api","text":"data.frame parsed TikTok videos user posted","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Lookup TikTok information about a user using the research API — tt_user_info_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_user_info_api(\"jbgruber\") # OR tt_user_info_api(\"https://www.tiktok.com/@tiktok\") # OR tt_user_info(\"https://www.tiktok.com/@tiktok\") } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Get infos about a user from the hidden API — tt_user_info_hidden","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"Get infos user hidden API","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"","code":"tt_user_info_hidden(username, parse = TRUE)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"username URL video username. parse Whether parse data data.frame (set FALSE get full list).","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"data.frame user info.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get infos about a user from the hidden API — tt_user_info_hidden","text":"","code":"if (FALSE) { # \\dontrun{ df <- tt_user_info_hidden(\"https://www.tiktok.com/@fpoe_at\") } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Lookup which videos were liked by a user using the research API — tt_user_liked_videos_api","text":"","code":"tt_user_liked_videos_api( username, fields = \"all\", max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL ) tt_get_liked( username, fields = \"all\", max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Lookup which videos were liked by a user using the research API — tt_user_liked_videos_api","text":"username name(s) user(s) queried fields fields returned (defaults ) max_pages results returned batches/pages 100 videos. many requested function stops? cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Lookup which videos were liked by a user using the research API — tt_user_liked_videos_api","text":"data.frame parsed TikTok videos user posted","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Lookup which videos were liked by a user using the research API — tt_user_liked_videos_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_get_liked(\"jbgruber\") # OR tt_user_liked_videos_api(\"https://www.tiktok.com/@tiktok\") # OR tt_user_liked_videos_api(\"https://www.tiktok.com/@tiktok\") # note: none of these work because nobody has this enabled! } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_pinned_videos_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Lookup which videos were pinned by a user using the research API — tt_user_pinned_videos_api","text":"","code":"tt_user_pinned_videos_api( username, fields = \"all\", cache = TRUE, verbose = TRUE, token = NULL ) tt_get_pinned( username, fields = \"all\", cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_pinned_videos_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Lookup which videos were pinned by a user using the research API — tt_user_pinned_videos_api","text":"fields fields returned (defaults ) cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_pinned_videos_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Lookup which videos were pinned by a user using the research API — tt_user_pinned_videos_api","text":"data.frame parsed TikTok videos user posted","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_pinned_videos_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Lookup which videos were pinned by a user using the research API — tt_user_pinned_videos_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_get_pinned(\"jbgruber\") # OR tt_user_pinned_videos_api(\"https://www.tiktok.com/@tiktok\") # OR tt_user_pinned_videos_api(\"https://www.tiktok.com/@tiktok\") } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_reposted_api.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Lookup which videos were liked by a user using the research API — tt_user_reposted_api","text":"","code":"tt_user_reposted_api( username, fields = \"all\", max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL ) tt_get_reposted( username, fields = \"all\", max_pages = 1, cache = TRUE, verbose = TRUE, token = NULL )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_reposted_api.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Lookup which videos were liked by a user using the research API — tt_user_reposted_api","text":"username name(s) user(s) queried fields fields returned (defaults ) max_pages results returned batches/pages 100 videos. many requested function stops? cache progress saved current session? can retrieved last_query() error occurs. function use extra memory. verbose function print status updates screen? token authentication token (usually supplied automatically running auth_research )","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_reposted_api.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Lookup which videos were liked by a user using the research API — tt_user_reposted_api","text":"data.frame parsed TikTok videos user posted","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_reposted_api.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Lookup which videos were liked by a user using the research API — tt_user_reposted_api","text":"","code":"if (FALSE) { # \\dontrun{ tt_get_reposted(\"jbgruber\") # OR tt_user_reposted_api(\"https://www.tiktok.com/@tiktok\") # OR tt_user_reposted_api(\"https://www.tiktok.com/@tiktok\") # note: none of these work because nobody has this enabled! } # }"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":null,"dir":"Reference","previous_headings":"","what":"Get videos from a TikTok user's profile — tt_user_videos_hidden","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"Get videos posted TikTok user.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"","code":"tt_user_videos_hidden( username, solve_captchas = FALSE, return_urls = FALSE, timeout = 5L, verbose = TRUE, ... )"},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"username username TikTok user whose hidden videos want retrieve. solve_captchas open browser solve appearing captchas manually. return_urls return video URLs instead downloading vidoes. timeout time (seconds) wait scrolling solving captchas. verbose function print status updates screen? ... Additional arguments passed tt_videos_hidden function.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"list video data URLs, depending value return_urls.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"function uses rvest scrape TikTok user's profile retrieve hidden videos.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get videos from a TikTok user's profile — tt_user_videos_hidden","text":"","code":"if (FALSE) { # \\dontrun{ # Get hidden videos from the user \"fpoe_at\" tt_user_videos_hidden(\"fpoe_at\") } # }"},{"path":[]},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"","code":"tt_videos_hidden( video_urls, save_video = TRUE, overwrite = FALSE, dir = \".\", cache_dir = NULL, sleep_pool = 1:10, max_tries = 5L, cookiefile = NULL, verbose = TRUE, ... ) tt_videos(...)"},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"video_urls vector URLs TikTok videos. save_video logical. videos downloaded. overwrite logical. save_video=TRUE file already exists, overwritten? dir directory save videos files . cache_dir set path, one RDS file metadata written disk video. useful many videos want pick left something goes wrong. sleep_pool vector numbers waiting period randomly drawn. max_tries often retry request fails. cookiefile path cookiefile. See vignette(\"unofficial-api\", package = \"traktok\") information authentication. verbose function print status updates screen? ... handed tt_videos_hidden (tt_videos) () tt_request_hidden.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"data.frame","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"function wait scraping two videos make less obvious scraper accessing site. period drawn randomly `sleep_pool` multiplied random fraction. Note video file requested session metadata. URL video file included metadata, link work cases.","code":""},{"path":"https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Get video metadata and video files from URLs — tt_videos_hidden","text":"","code":"if (FALSE) { # \\dontrun{ tt_videos(\"https://www.tiktok.com/@tiktok/video/7106594312292453675\") } # }"},{"path":"https://jbgruber.github.io/traktok/news/index.html","id":"traktok-005","dir":"Changelog","previous_headings":"","what":"traktok 0.0.5","title":"traktok 0.0.5","text":"adds experimental tt_user_videos_hidden tt_user_info_hidden rely chromote","code":""}] diff --git a/sitemap.xml b/sitemap.xml index 31971b3..0ef34bc 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -15,6 +15,7 @@ https://jbgruber.github.io/traktok/reference/print.tt_results.html https://jbgruber.github.io/traktok/reference/query.html https://jbgruber.github.io/traktok/reference/tt_comments_api.html +https://jbgruber.github.io/traktok/reference/tt_get_follower.html https://jbgruber.github.io/traktok/reference/tt_get_following_hidden.html https://jbgruber.github.io/traktok/reference/tt_json.html https://jbgruber.github.io/traktok/reference/tt_playlist_api.html @@ -26,6 +27,8 @@ https://jbgruber.github.io/traktok/reference/tt_user_info_api.html https://jbgruber.github.io/traktok/reference/tt_user_info_hidden.html https://jbgruber.github.io/traktok/reference/tt_user_liked_videos_api.html +https://jbgruber.github.io/traktok/reference/tt_user_pinned_videos_api.html +https://jbgruber.github.io/traktok/reference/tt_user_reposted_api.html https://jbgruber.github.io/traktok/reference/tt_user_videos_hidden.html https://jbgruber.github.io/traktok/reference/tt_videos_hidden.html

    Descriptiontt_user_info tt_user_info_api-tt_user_videos_hidden
    get user infott_user_infott_user_info_apitt_user_videos_hidden
    get comments under a video tt_comments tt_comments_api -
    get who follows a user tt_get_follower-tt_user_follower_api tt_get_follower_hidden
    get who a user is following tt_get_following-tt_user_following_api tt_get_following_hidden
    get videos a user likedtt_get_likedtt_user_liked_videos_api-
    get pinned videos of userstt_get_pinnedtt_user_pinned_videos_api-
    get videos in a playlisttt_playlisttt_playlist_api-
    get raw video data -