Skip to content

Usage

There are two ways to use Tracker Scraper: the scrape() function in your own Python code, and the tracker-scraper command-line tool. Both do the same thing — contact a tracker and return per-torrent stats.

The package exposes a single public function:

from tracker_scraper import scrape
results = scrape(tracker, hashes)
ArgumentTypeDescription
trackerstrThe tracker’s announce URL, taken straight from a torrent’s metadata. Scheme must be udp, http, or https.
hasheslist[str]One or more torrent info_hash values as 40-character hex strings.

It returns a dict keyed by info_hash, where each value is a dict with three counts:

KeyMeaning
seedsNumber of complete copies currently seeding.
peersNumber of incomplete peers (leechers) currently downloading.
completeNumber of times the torrent has been downloaded to completion.
from tracker_scraper import scrape
results = scrape(
tracker="udp://exodus.desync.com:6969",
hashes=["2d88e693eda7edf3c1fd0c48e8b99b8fd5a820b2"],
)
for info_hash, stats in results.items():
print(info_hash, stats["seeds"], stats["peers"], stats["complete"])

The scheme of the announce URL decides the protocol — you don’t choose it explicitly:

  • udp://… → the binary UDP tracker protocol. Fast and the most common form for modern trackers.
  • http://… or https://… → the bencoded HTTP scrape endpoint. The URL’s announce path segment is automatically rewritten to scrape, as the convention requires.
# UDP
scrape("udp://tracker.opentrackr.org:1337/announce", hashes)
# HTTP — the /announce path is rewritten to /scrape for you
scrape("http://tracker.example.org/announce", hashes)

Pass several hashes to query them all in one round trip:

results = scrape(
tracker="udp://exodus.desync.com:6969",
hashes=[
"2d88e693eda7edf3c1fd0c48e8b99b8fd5a820b2",
"8929b29b83736ae650ee8152789559355275bd5c",
],
)

Installing the package also installs a tracker-scraper command. It takes the tracker as the first argument and one or more hashes after it, and prints the results as JSON:

Terminal window
tracker-scraper udp://exodus.desync.com:6969 \
2d88e693eda7edf3c1fd0c48e8b99b8fd5a820b2 \
8929b29b83736ae650ee8152789559355275bd5c
{
"2d88e693eda7edf3c1fd0c48e8b99b8fd5a820b2": {
"seeds": 34,
"peers": 189,
"complete": 10
},
"8929b29b83736ae650ee8152789559355275bd5c": {
"seeds": 12,
"peers": 0,
"complete": 290
}
}
Flag / argumentDescription
trackerAnnounce URL of the tracker (udp://, http://, or https://).
hashesOne or more 40-character hex info_hash values.
--indent NJSON indentation for the printed output (default 2).
-h, --helpShow the usage summary.

The command exits with status 0 on success and 1 if the scrape fails (the error message is written to stderr), which makes it easy to use in shell scripts.

The same tool is available as a module if you prefer:

Terminal window
python -m tracker_scraper udp://exodus.desync.com:6969 2d88e693eda7edf3c1fd0c48e8b99b8fd5a820b2

Network and protocol problems surface as exceptions (Python API) or a non-zero exit code (CLI). Wrap calls you don’t control:

from tracker_scraper import scrape
try:
results = scrape("udp://tracker.example:6969", hashes)
except RuntimeError as exc:
print(f"Scrape failed: {exc}")
except OSError as exc:
# socket timeout / DNS failure / connection refused
print(f"Network error: {exc}")
  • Configuration — argument reference, the return shape, timeouts, and logging.
  • Examples — runnable UDP, HTTP, and CLI recipes.