1337x - Buscador CLI de Torrents
Ojala siempre hubiese una api detrás de un buscador de torrents, como el de mi otro artículo que podés usar una api libremente y buscar en ThePirateBay, pero no siempre tenemos esa suerte y no queda otra que el lío de scrapear un html.
Cuando intenté hacer scraping sobre https://1337x.to/search/violet+myers/1/
, me encontré con una protección de Cloudflare que impedía que curl
o cualquier otro cliente sin navegador pudiera acceder.
Sin embargo, descubrí que las búsquedas por categoría como https://1337x.to/category-search/violet%20myers/XXX/1/
no tienen protección de Cloudflare y devuelven HTML sin verificación alguna
Así que... vamos a scrapear…. un chino...lo odio!!!
El script
Este script muestra una lista de torrents con más seeds, solo los primeros 40 que encuentre (los que corresponden a la primera página de la búsqueda) con fzf
para elegir uno y obtener su enlace magnet. Simple y conciso
Su uso es:
./1337x.sh texto+a+buscar CATEGORIA
Vamos con el código:
#!/bin/sh
# Uso: 1337x.sh texto+a+buscar CATEGORIA
SEARCH_TERM=$1
CATEGORY=$2
# Validar categorias
#
case "$CATEGORY" in
Movies|XXX|TV|Games|Music|Apps|Documentaries)
;; # Si es válida, seguir sin hacer nada
*)
# Si no es válida, mostrar mensaje de error y salir
echo "Categoría inválida. Usar: Movies XXX TV Games Music Apps Documentaries"
exit 1
;;
esac
# URLs
BASE_URL="https://1337x.to/category-search"
SEARCH_URL="${BASE_URL}/${SEARCH_TERM}/${CATEGORY}/1/"
echo "Buscando en: $SEARCH_URL"
# archivos temporales
TEMP_FILE=$(mktemp) # HTML completo
TEMP_LINKS=$(mktemp) # Lista de URLs
TEMP_INDEXED=$(mktemp) # Resultados numerados
TEMP_NUMBERS=$(mktemp) # nros de índice
TEMP_FORMATTED=$(mktemp) # Nombres limpios para mostrar en fzf
TORRENT_PAGE=$(mktemp) # HTML completo un torrent
# Funcion de limpieza para borrar los archivos temporales al terminar o si se corta
cleanup() {
rm -f "$TEMP_FILE" "$TEMP_LINKS" "$TEMP_INDEXED" "$TEMP_NUMBERS" "$TEMP_FORMATTED" "$TORRENT_PAGE"
}
trap cleanup EXIT INT TERM
# Descargar web búsqueda
curl -s -A "Mozilla/5.0" "$SEARCH_URL" > "$TEMP_FILE" || {
echo "Error: No se pudo descargar la página"
exit 1
}
INDEX=1 # Contador de resultados
# Busca paths de los torrents (URLs onda /torrent/1234/Nombre)
grep -o '/torrent/[0-9]*/[^"]*' "$TEMP_FILE" | while IFS= read -r torrent_path; do
# Extrae línea completa que contiene el path
LINE=$(grep -F "$torrent_path" "$TEMP_FILE" | head -1)
if [ -n "$LINE" ]; then
# Intenta tener el nombre desde el HTML
NAME=$(echo "$LINE" | sed 's/.*<a[^>]*>\([^<]*\)<\/a>.*/\1/' | sed 's/&/\&/g; s/</</g; s/>/>/g; s/"/"/g')
# Si no se pudo, genera uno desde la URL
if [ -z "$NAME" ] || [ "$NAME" = "$LINE" ]; then
NAME=$(echo "$torrent_path" | sed 's|/torrent/[0-9]*/||; s/-/ /g' | cut -c1-50)
fi
# Scrapea seeds, leechers y tamaño
CONTEXT=$(grep -A5 -B5 -F "$torrent_path" "$TEMP_FILE" | tr '\n' ' ')
SEEDERS=$(echo "$CONTEXT" | grep -o 'seeds">[0-9]*<' | sed 's/.*seeds">//; s/<.*//' | head -1)
LEECHERS=$(echo "$CONTEXT" | grep -o 'leeches">[0-9]*<' | sed 's/.*leeches">//; s/<.*//' | head -1)
SIZE=$(echo "$CONTEXT" | grep -o 'size[^>]*>[^<]*<' | sed 's/.*>//; s/<.*//' | head -1)
# Si alguno está empty, usa "!"
[ -z "$SEEDERS" ] && SEEDERS="!"
[ -z "$LEECHERS" ] && LEECHERS="!"
[ -z "$SIZE" ] && SIZE="!"
# Si el nombre está ok, imprime resultado y guarda el enlace
if [ -n "$NAME" ]; then
# Mostrar resultado con formato: número) nombre | S:seeds L:leechers | tamaño
printf "%d) %-58s | S:%-4s L:%-4s | %s\n" "$INDEX" "$NAME" "$SEEDERS" "$LEECHERS" "$SIZE"
echo "https://1337x.to$torrent_path"
INDEX=`expr "$INDEX" + 1` # Incrementar índice
fi
fi
done > "$TEMP_INDEXED"
# Extraer nros de índice
sed 's/) .*//' "$TEMP_INDEXED" > "$TEMP_NUMBERS"
# Extrae los nombres limpios (sin número ni URL)
grep -v '^https://' "$TEMP_INDEXED" | sed 's/^[0-9]*) //' > "$TEMP_FORMATTED"
# Extrae URLs de los torrents
sed -n '/^https:\/\//p' "$TEMP_INDEXED" > "$TEMP_LINKS"
# Verifica si hay resultados ok
if [ ! -s "$TEMP_FORMATTED" ]; then
echo "No se encontraron reultados"
TORRENT_COUNT=$(grep -c '/torrent/' "$TEMP_FILE" 2>/dev/null || echo "0")
echo "Enlaces encontrados: $TORRENT_COUNT"
grep '/torrent/' "$TEMP_FILE" | head -3 | sed 's/^/ /'
# Si el HTML contiene algún mensaje de "sin resultados" lo avisa
grep -qi "no.*result\|not.*found\|nothing.*found" "$TEMP_FILE" && echo "Sin resultados"
exit 1
fi
# Muestra cantidad de resultados
echo "Encontrados $(wc -l < "$TEMP_FORMATTED") resultados"
echo "Selecciona un torrent:"
# Muestra lista con fzf
SELECTED=$(cat "$TEMP_FORMATTED" | fzf --height=20 --layout=reverse --border --prompt="Selecciona un torrent: " --preview-window=hidden)
# Si no se seleccionó nada slair
[ -z "$SELECTED" ] && echo "No seleccionado" && exit 1
# Obvia caracteres especiales para usar en grep
ESCAPED=$(echo "$SELECTED" | sed 's/[][\\.^$*]/\\&/g')
# Buscar el número de línea
LINE_NUM=$(grep -n "$ESCAPED" "$TEMP_FORMATTED" | cut -d: -f1 | head -1)
# Obtiene la URL del torrent elegido
TORRENT_URL=$(sed -n "${LINE_NUM}p" "$TEMP_LINKS")
# Si no hay URL, error
[ -z "$TORRENT_URL" ] && echo "Error al obtener el torrent" && exit 1
echo "Obteniendo magnet de: $TORRENT_URL"
# Descargar la página del torrent seleccionado para luego buscar el magnet
curl -s -A "Mozilla/5.0" "$TORRENT_URL" > "$TORRENT_PAGE" || {
echo "Error al obtener la página del torrent"
exit 1
}
# Busca el magnet
MAGNET_LINK=$(grep -o 'magnet:[^"]*' "$TORRENT_PAGE" | head -1)
# Muestra el enlace magnet o error si no se encuentra
if [ -n "$MAGNET_LINK" ]; then
echo ""
echo "========== ENLACE MAGNET =========="
echo "$MAGNET_LINK"
echo "==================================="
else
echo "No se encontró enlace magnet"
exit 1
fi
Requisitos
-
curl
-
fzf
-
sed
-
grep
-
tr
-
mktemp
En fin…
Con este script podés buscar torrents desde la terminal; está propenso a fallos por cambios que puedan hacer en la web….así que crucemos los dedos….
Tags: Scripts