Skip to content

johnlester-0369/lyrics-scraper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lyrics-scraper

Search for any song and print its full lyrics to your terminal — no API key, no account, no config.

Node.js License: ISC


The Problem

Every lyrics API either requires an account, charges for access, or hides results behind a client-side JavaScript wall.

lyrics-scraper skips all of that — one command, full lyrics, nothing else.


Quick Start

git clone https://github.com/johnlester-0369/lyrics-scraper.git
cd lyrics-scraper
npm install
node index.js Ava Max Torn

Expected output:

Searching for: Ava Max Torn

Fetching lyrics from: https://genius.com/Ava-max-torn-lyrics

[Verse 1]
You, you take all of the li-li-light away
...

Usage

node index.js <song name>

All arguments after node index.js are joined into a single query — shell quoting is never required.

# Single-word query
node index.js Torn

# Multi-word title — no quotes needed
node index.js Ava Max Torn

# Artist + title
node index.js Kendrick Lamar Not Like Us

Prerequisites

  • Node.js ≥ 14 — required for native ES module support ("type": "module" is set in package.json)
  • npm — bundled with Node.js

How It Works

Three steps run on every invocation:

1. Search Calls the Genius internal search API (/api/search/song?q=<query>) with the joined argument string. The top-ranked hit is selected — Genius orders results by relevance, so index 0 is the closest match. The result's fully-qualified URL is passed to the scraper.

2. Fetch Retrieves the lyrics page using a real browser User-Agent header. Genius returns a JavaScript-only shell to headless clients; spoofing the header triggers the fully server-rendered HTML with lyrics embedded in [data-lyrics-container] divs.

3. Extract Genius splits a song's lyrics across multiple [data-lyrics-container] divs with ad units injected between them in the DOM. Each container is cleaned independently before extraction:

  • <br> tags are replaced with \n before .text() — Cheerio's text extractor silently drops all tags, producing run-together lines if <br> is not converted first
  • [data-exclude-from-selection] blocks are removed — these wrap the contributor count, translation links, song title, and bio preview that appear visually inside the first lyrics container but are not lyric content
  • Zero-width <span tabindex="0"> accessibility elements are removed — they produce empty text fragments in the extracted output
  • Empty containers are skipped — Genius sometimes renders placeholder divs that match the selector but contain no lyric content

All cleaned containers are joined with double newlines to reconstruct the full song.


Known Limitations

  • DOM dependency — scraping is tied to Genius's current HTML structure. If Genius changes the [data-lyrics-container] attribute or injects non-lyric content into containers differently, extraction will break or produce incorrect output.
  • Top result only — the search always selects the first hit. Ambiguous queries (e.g., node index.js Torn without an artist name) may return a cover, remix, or unrelated track.
  • Rate limiting — Genius may throttle or block rapid repeated requests from the same IP address.
  • Lyrics-only pages — requesting a URL that does not contain [data-lyrics-container] divs throws an explicit error. Genius artist pages, album pages, and annotations will not work.

Tech Stack

Package Version Purpose
axios ^1.13.6 HTTP requests to Genius search API and lyrics pages
cheerio ^1.2.0 Server-side HTML parsing and DOM traversal for lyric extraction

License

ISC

About

Search for any song and print its full lyrics to your terminal — no API key, no account, no config.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors