{"id":18562959,"url":"https://github.com/josiahparry/genius","last_synced_at":"2025-11-01T13:30:31.284Z","repository":{"id":49429502,"uuid":"92510516","full_name":"JosiahParry/genius","owner":"JosiahParry","description":"Easily access song lyrics from Genius in a tibble. ","archived":false,"fork":false,"pushed_at":"2021-10-31T15:29:00.000Z","size":438,"stargazers_count":121,"open_issues_count":2,"forks_count":18,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-13T19:49:24.727Z","etag":null,"topics":["music-information-retrieval","song-lyrics","text-mining"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JosiahParry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-26T12:54:41.000Z","updated_at":"2025-02-08T14:18:53.000Z","dependencies_parsed_at":"2022-09-08T01:10:33.360Z","dependency_job_id":null,"html_url":"https://github.com/JosiahParry/genius","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JosiahParry%2Fgenius","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JosiahParry%2Fgenius/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JosiahParry%2Fgenius/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JosiahParry%2Fgenius/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JosiahParry","download_url":"https://codeload.github.com/JosiahParry/genius/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239293959,"owners_count":19615041,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["music-information-retrieval","song-lyrics","text-mining"],"created_at":"2024-11-06T22:11:31.212Z","updated_at":"2025-11-01T13:30:31.241Z","avatar_url":"https://github.com/JosiahParry.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## NOTE: genius no longer under development\n\n2021-10-31 \n\nAfter quite some time I have decided to no longer maintain or support the `genius` package. While this package serves a very important purpose from the perspective of music information retrieval, it lies in a grey legal area—web scraping. \n\nOver the years genius.com has changed their web practices in such a way that makes it increasingly unreliable and difficult to scrape. \n\nWhy not use the API (as many have asked)? Because song lyrics are owned by the musicians themselves and as such, they cannot be provided via their API.\n\n\nI will be removing this package from CRAN. \n\n\n------\n\n\n\n[![CRAN status](https://www.r-pkg.org/badges/version/genius)](https://cran.r-project.org/package=genius)\n[![CRAN RStudio mirror downloads](https://cranlogs.r-pkg.org/badges/grand-total/genius?color=d3a167)](https://r-pkg.org/pkg/genius)\n[![lifecycle](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://www.tidyverse.org/lifecycle/#maturing)\n\nThis package was created to provide an easy method to access lyrics as text data using [Genius](https://genius.com).\n\nAccess to genius as an API or via Python [here](https://github.com/JosiahParry/genius-api)\n\nInstallation\n------------\n\nThis package is available from CRAN.\n\n``` r\ninstall.packages(\"genius\")\n```\n\nLoad the package:\n\n``` r\nlibrary(genius)\nlibrary(tidyverse)\n```\n\nGet started with a tutorial! \n\n```r \nlearnr::run_tutorial(\"genius_tutorial\", \"genius\")\n```\n\nGetting Lyrics\n==============\n\nWhole Albums\n------------\n\n`genius_album()` allows you to download the lyrics for an entire album in a `tidy` format. There are two arguments `artists` and `album`. Supply the quoted name of artist and the album (if it gives you issues check that you have the album name and artists as specified on [Genius](https://genius.com)).\n\nThis returns a tidy data frame with three columns:\n\n-   `title`: track name\n-   `track_n`: track number\n-   `text`: lyrics\n\n``` r\nemotions_math \u003c- genius_album(artist = \"Margaret Glaspy\", album = \"Emotions and Math\")\n```\n\n    ## Joining, by = c(\"track_title\", \"track_n\", \"track_url\")\n\n``` r\nemotions_math\n```\n\n    ## # A tibble: 370 x 4\n    ##    track_title       track_n  line lyric                                 \n    ##    \u003cchr\u003e               \u003cint\u003e \u003cint\u003e \u003cchr\u003e                                 \n    ##  1 Emotions And Math       1     1 Oh when I got you by my side          \n    ##  2 Emotions And Math       1     2 Everything's alright                  \n    ##  3 Emotions And Math       1     3 Its just when your gone               \n    ##  4 Emotions And Math       1     4 I start to snooze the alarm           \n    ##  5 Emotions And Math       1     5 Cause I stay up until 4 in the morning\n    ##  6 Emotions And Math       1     6 Counting all the days 'til you're back\n    ##  7 Emotions And Math       1     7 Shivering in an ice cold bath         \n    ##  8 Emotions And Math       1     8 Of emotions and math                  \n    ##  9 Emotions And Math       1     9 Oh it's a shame                       \n    ## 10 Emotions And Math       1    10 And I'm to blame                      \n    ## # … with 360 more rows\n\nMultiple Albums / Songs\n-----------------------\n\nIf you wish to download multiple albums from multiple artists, try and keep it tidy and avoid binding rows if you can. We can achieve this in a tidy workflow by creating a tibble with two columns: `artist` and `album` where each row is an artist and their album. We can then iterate over those columns with `add_genius()`.\n\nPipe a dataframe with a column for the album artists and album/track information. The argument `type` is used to indicate if the dataframe contains songs or albums\n\n``` r\n# Example with 2 different artists and albums\nartist_albums \u003c- tribble(\n ~artist, ~album,\n \"J. Cole\", \"KOD\",\n \"Sampha\", \"Process\"\n)\n\n\nartist_albums %\u003e%\n add_genius(artist, album)\n```\n\n    ## Joining, by = c(\"track_title\", \"track_n\", \"track_url\")\n    ## Joining, by = c(\"track_title\", \"track_n\", \"track_url\")\n\n    ## Joining, by = c(\"artist\", \"album\")\n\n    ## # A tibble: 1,319 x 6\n    ##    artist  album track_title track_n  line lyric                           \n    ##    \u003cchr\u003e   \u003cchr\u003e \u003cchr\u003e         \u003cint\u003e \u003cint\u003e \u003cchr\u003e                           \n    ##  1 J. Cole KOD   Intro (KOD)       1     1 Can someone please turn off my …\n    ##  2 J. Cole KOD   Intro (KOD)       1     2 My thoughts are racing all the …\n    ##  3 J. Cole KOD   Intro (KOD)       1     3 There is no reason or no rhyme  \n    ##  4 J. Cole KOD   Intro (KOD)       1     4 I'm trapped inside myself       \n    ##  5 J. Cole KOD   Intro (KOD)       1     5 A newborn baby has two primary …\n    ##  6 J. Cole KOD   Intro (KOD)       1     6 \"Laughter, which says, \\\"I love…\n    ##  7 J. Cole KOD   Intro (KOD)       1     7 \"Or crying, which says, \\\"This …\n    ##  8 J. Cole KOD   Intro (KOD)       1     8 There are many ways to deal wit…\n    ##  9 J. Cole KOD   Intro (KOD)       1     9 Choose wisely                   \n    ## 10 J. Cole KOD   Intro (KOD)       1    10 At the bottom of the hourglass  \n    ## # … with 1,309 more rows\n\nThis can be easily replicated with multiple songs as well.\n\n``` r\n# Example with 2 different artists and songs\nartist_songs \u003c- tribble(\n ~artist, ~track,\n \"J. Cole\", \"Motiv8\",\n \"Andrew Bird\", \"Anonanimal\"\n)\n\nartist_songs %\u003e%\n add_genius(artist, track, type = \"lyrics\")\n```\n\n    ## Joining, by = c(\"artist\", \"track\")\n\n    ## # A tibble: 102 x 5\n    ##    artist  track  track_title  line lyric                                  \n    ##    \u003cchr\u003e   \u003cchr\u003e  \u003cchr\u003e       \u003cint\u003e \u003cchr\u003e                                  \n    ##  1 J. Cole Motiv8 Motiv8          1 You really wanna know who Superman is? \n    ##  2 J. Cole Motiv8 Motiv8          2 Watch this, pow!                       \n    ##  3 J. Cole Motiv8 Motiv8          3 I like him                             \n    ##  4 J. Cole Motiv8 Motiv8          4 I think he's pretty cool               \n    ##  5 J. Cole Motiv8 Motiv8          5 He's my idol                           \n    ##  6 J. Cole Motiv8 Motiv8          6 I can't have no sympathy for fuck…\n    ##  7 J. Cole Motiv8 Motiv8          7 All this shit I've seen done made my b…\n    ##  8 J. Cole Motiv8 Motiv8          8 Spill promethazine inside a double cup \n    ##  9 J. Cole Motiv8 Motiv8          9 Double up my cream, now that's a Doubl…\n    ## 10 J. Cole Motiv8 Motiv8         10 Please don't hit my phone if it ain't …\n    ## # … with 92 more rows\n\nSong Lyrics\n-----------\n\n### `genius_lyrics()`\n\nIf you want only a single song, you can use `genius_lyrics()`. Supply an artist and a song title as character strings, and voila.\n\n``` r\nmemory_street \u003c- genius_lyrics(artist = \"Margaret Glaspy\", song = \"Memory Street\")\n\nmemory_street\n```\n\n    ## # A tibble: 27 x 3\n    ##    track_title    line lyric                                  \n    ##    \u003cchr\u003e         \u003cint\u003e \u003cchr\u003e                                  \n    ##  1 Memory Street     1 Ring the alarm                         \n    ##  2 Memory Street     2 I'm on memory street                   \n    ##  3 Memory Street     3 With him on my arm                     \n    ##  4 Memory Street     4 And my feet on the dash of that car    \n    ##  5 Memory Street     5 I don't dare                           \n    ##  6 Memory Street     6 Walk down memory street                \n    ##  7 Memory Street     7 Why remember                           \n    ##  8 Memory Street     8 All the times I took forever to forget?\n    ##  9 Memory Street     9 Call the guards                        \n    ## 10 Memory Street    10 I'm at the gates                       \n    ## # … with 17 more rows\n\nThis returns a `tibble` with three columns `title`, `text`, and `line`. However, you can specifiy additional arguments to control the amount of information to be returned using the `info` argument.\n\n-   `info = \"title\"` (default): Return the lyrics, line number, and song title.\n-   `info = \"simple\"`: Return just the lyrics and line number.\n-   `info = \"artist\"`: Return the lyrics, line number, and artist.\n-   `info = \"features\"`: Returns the lyrics, line number, artist, verse, and vocalist if available.\n-   `info = \"all\"`: Return lyrics, line number, song title, artist.\n\nTracklists\n----------\n\n`genius_tracklist()`, given an `artist` and an `album` will return a barebones `tibble` with the track title, track number, and the url to the lyrics.\n\n``` r\ngenius_tracklist(artist = \"Basement\", album = \"Colourmeinkindness\") \n```\n\n    ## # A tibble: 10 x 3\n    ##    track_title track_n track_url                                   \n    ##    \u003cchr\u003e         \u003cint\u003e \u003cchr\u003e                                       \n    ##  1 Whole             1 https://genius.com/Basement-whole-lyrics    \n    ##  2 Covet             2 https://genius.com/Basement-covet-lyrics    \n    ##  3 Spoiled           3 https://genius.com/Basement-spoiled-lyrics  \n    ##  4 Pine              4 https://genius.com/Basement-pine-lyrics     \n    ##  5 Bad Apple         5 https://genius.com/Basement-bad-apple-lyrics\n    ##  6 Breathe           6 https://genius.com/Basement-breathe-lyrics  \n    ##  7 Control           7 https://genius.com/Basement-control-lyrics  \n    ##  8 Black             8 https://genius.com/Basement-black-lyrics    \n    ##  9 Comfort           9 https://genius.com/Basement-comfort-lyrics  \n    ## 10 Wish             10 https://genius.com/Basement-wish-lyrics\n\n------------------------------------------------------------------------\n\nNitty Gritty\n------------\n\n`genius_lyrics()` generates a url via `gen_song_url()` to Genius which is fed to `genius_url()`, the function that does the heavy lifting of actually fetching lyrics.\n\nI have not figured out all of the patterns that are used for generating the Genius.com urls, so errors are bound to happen. If `genius_lyrics()` returns an error. Try utilizing `genius_tracklist()` and `genius_url()` together to get the song lyrics.\n\nFor example, say \"(No One Knows Me) Like the Piano\" by *Sampha* wasn't working in a standard `genius_lyrics()` call.\n\n``` r\npiano \u003c- genius_lyrics(\"Sampha\", \"(No One Knows Me) Like the Piano\")\n```\n\nWe could grab the tracklist for the album *Process* which the song is from. We could then isolate the url for *(No One Knows Me) Like the Piano* and feed that into \\`genius\\_url().\n\n``` r\n# Get the tracklist for \nprocess \u003c- genius_tracklist(\"Sampha\", \"Process\")\n\n# Filter down to find the individual song\npiano_info \u003c- process %\u003e% \n  filter(track_title == \"(No One Knows Me) Like the Piano\")\n\n# Filter song using string detection\n# process %\u003e% \n#  filter(stringr::str_detect(title, coll(\"Like the piano\", ignore_case = TRUE)))\n\npiano_url \u003c- piano_info$track_url\n```\n\nNow that we have the url, feed it into `genius_url()`.\n\n``` r\ngenius_url(piano_url, info = \"simple\")\n```\n\n    ## # A tibble: 12 x 2\n    ##     line lyric                                                             \n    ##    \u003cint\u003e \u003cchr\u003e                                                             \n    ##  1     1 No one knows me like the piano in my mother's home                \n    ##  2     2 You would show me I had something some people call a soul         \n    ##  3     3 And you dropped out the sky, oh you arrived when I was three year…\n    ##  4     4 No one knows me like the piano in my mother's home                \n    ##  5     5 You know I left, I flew the nest                                  \n    ##  6     6 And you know I won't be long                                      \n    ##  7     7 And in my chest you know me best                                  \n    ##  8     8 And you know I'll be back home                                    \n    ##  9     9 An angel by her side, all of the times I knew we couldn't cope    \n    ## 10    10 They said that it's her time, no tears in sight, I kept the feeli…\n    ## 11    11 And you took hold of me and never, never, never let me go'Cause n…\n    ## 12    12 In my mother's home\n\n------------------------------------------------------------------------\n\nOn the Internals\n================\n\nGenerative functions\n--------------------\n\nThis package works almost entirely on pattern detection. The urls from *Genius* are (mostly) easily reproducible (shout out to [Angela Li](https://twitter.com/CivicAngela) for pointing this out).\n\nThe two functions that generate urls are `gen_song_url()` and `gen_album_url()`. To see how the functions work, try feeding an artist and song title to `gen_song_url()` and an artist and album title to `gen_album_url()`.\n\n``` r\ngen_song_url(\"Laura Marling\", \"Soothing\")\n```\n\n    ## [1] \"https://genius.com/Laura-Marling-Soothing-lyrics\"\n\n``` r\ngen_album_url(\"Daniel Caesar\", \"Freudian\")\n```\n\n    ## [1] \"https://genius.com/albums/Daniel-Caesar/Freudian\"\n\n`genius_lyrics()` calls `gen_song_url()` and feeds the output to `genius_url()` which preforms the scraping.\n\nGetting lyrics for albums is slightly more involved. It first calls `genius_tracklist()` which first calls `gen_album_url()` then using the handy package `rvest` scrapes the song titles, track numbers, and song lyric urls. Next, the song urls from the output are iterated over and fed to `genius_url()`.\n\n### Notes:\n\nAs this is my first *\"package\"* there will be many issues. Please submit an issue and I will do my best to attend to it.\n\nThere are already issues of which I am present (the lack of error handling). If you would like to take those on, please go ahead and make a pull request. Please contact me on [Twitter](https://twitter.com/josiahparry).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosiahparry%2Fgenius","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjosiahparry%2Fgenius","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosiahparry%2Fgenius/lists"}