همهٔ مقاله‌ها

· Casimiro Ferreira· 6 دقیقه مطالعه

معرفی اسکرپرهای پایگاه‌داده موسیقی ما

  • Scrapers
  • Media Metadata
  • Music
  • Python
  • FOSS

یک واسط برای تمام وب موسیقی

وب موسیقی در میان سایت‌های مستقل بسیاری تکه‌تکه است. Bandcamp به شما یک FLAC و یک مجوز Creative Commons می‌فروشد؛ SoundCloud یک ریمیکس را پخش می‌کند که هیچ‌کس دیگری آن را میزبانی نمی‌کند؛ SomaFM مجموعه‌ای از کانال‌های رادیویی مورد حمایت شنوندگان را اداره می‌کند؛ و شماری از سایت‌های اداره‌شده توسط جامعه، دانشنامه‌هایی گلچین‌شده از راک پیشرو، جاز، کلاسیک و متال را نگه می‌دارند. هر سایت نشانه‌گذاری خاص خود، عادت‌های خاص خود و برداشت خاص خود از این‌که یک «قطعه» اصلاً چیست را دارد.

ما خانواده‌ای از کلاینت‌های کوچک، متمرکز و متن‌باز پایتون را نگهداری می‌کنیم که این آشفتگی را رام می‌کنند. همه آن‌ها در جوهر خود یک کار انجام می‌دهند: به یک منبع موسیقی دست می‌یابند و مدل‌های تایپ‌شده متادیتای رسانه‌ای را به شما بازمی‌گردانند — اشیای اعتبارسنجی‌شده به‌جای دیکشنری‌های شکننده — تا بقیه کد شما هرگز نیازی به دانستن این‌که داده از کدام سایت آمده نداشته باشد. هفت‌تا از این نه کلاینت روی PyPI منتشر شده‌اند؛ آن دوتای دیگر مستقیماً از GitHub نصب می‌شوند. همه به یک زبان صحبت می‌کنند.

این هم گشت ما.

استریم و رادیو

py_bandcamp از Bandcamp اسکرپ می‌کند: جست‌وجوی قطعات، آلبوم‌ها، هنرمندان و لیبل‌ها؛ مرور بر اساس برچسب ژانر؛ دریافت پیشنهادها و هنرمندان مرتبط از یک دانه؛ و استخراج یک URL قابل‌استریم MP3. جست‌وجوها اشیای تایپ‌شده Release را بازمی‌گردانند که عنوان، تصویر جلد، ژانرها، اعتبارها و — که برای علاقه‌مندان به FOSS اهمیت حیاتی دارد — یک فیلد مجوز به سبک SPDX با یک بررسی is_open() را حمل می‌کنند تا بتوانید یک انتشار Creative Commons را از یک انتشار با تمام حقوق محفوظ تشخیص دهید. یک تبدیل آلبوم با وفاداری کامل، فهرست قطعات مرتب‌شده را به‌صورت درخواستی پر می‌کند.

nuvem_de_som کلاینت SoundCloud ماست و چاقوی سوئیسی این مجموعه است. سه بک‌اند مستقل — یک بک‌اند API غنی از متادیتا، یک اسکرپر HTML بدون وابستگی و یک بک‌اند yt-dlp — پشت یک ارکستریتور قرار می‌گیرند که به‌آرامی از یکی به بعدی عقب می‌نشیند. قطعات و افراد را جست‌وجو می‌کند، URL های مستقیم استریم (progressive یا HLS) را resolve می‌کند، قطعات و کل پلی‌لیست‌ها را دانلود می‌کند و حتی یک اپلیکیشن ترمینال به نام nds برای جست‌وجو و پخش از خط فرمان را همراه دارد. انتشارها با codec، bitrate، ژانرها، کشور، مجوز SPDX و فهرست کامل قطعات مجموعه‌ها بازمی‌گردند.

radiosoma API عمومی کانال‌های SomaFM را دربرمی‌گیرد. SomaFM سر دوستانه و با API باز این طیف است و کلاینت آن را به‌طور تمیز مدل می‌کند: هر کانال یک اثر است و هر رمزگذاری استریم — AAC با ۱۳۰ kbps، MP3 با ۲۵۶ kbps، HE-AAC با ۶۴ و ۳۲ kbps — به Release مخصوص خود از آن کانال تبدیل می‌شود، تا یک مصرف‌کننده بتواند بهترین گزینه را انتخاب کند و بر اساس هویت حذف تکرار کند. فید قطعات اخیر به‌شکل یک برنامه مرتب از آنچه در حال پخش بوده ظاهر می‌شود.

tunein یک کلاینت غیررسمی TuneIn برای ایستگاه‌های رادیوی خطی و IPTV جهان است. یک مسیر سریع فقط payload جست‌وجو را بازمی‌گرداند؛ یک فراخوانی غنی‌سازی اختیاری، ژانر، زبان، کشور، علامت‌ فراخوان و شعار را پر می‌کند. از آنجا که TuneIn به‌ازای هر ایستگاه چندین URL استریم بازمی‌گرداند — bitrate های مختلف، آینه‌ها و پروتکل‌ها — هرکدام به Release مخصوص خود تبدیل می‌شود و باز هم به مصرف‌کننده اجازه انتخاب در زمان پخش را می‌دهد. یک CLI کوچک به شما خروجی جدولی یا JSON می‌دهد.

pyheartradio با API عمومی iHeartRadio صحبت می‌کند — بدون کلید، بدون حساب. ایستگاه‌ها، پادکست‌ها، هنرمندان، قطعات و پلی‌لیست‌ها را جست‌وجو می‌کند؛ قسمت‌های پادکست را با URL های مستقیم استریم صوتی بازیابی می‌کند؛ و بر دریافت‌های جزئیات موازی تکیه دارد تا جست‌وجوهای ایستگاه و هنرمند به‌طور همزمان اجرا شوند. هر مدل، کمک‌کننده‌های to_external_ids() و to_signals() را ارائه می‌دهد تا مستقیماً در یک پایپ‌لاین متادیتای تایپ‌شده جا بگیرد.

دانشنامه‌ها و آرشیوهای موسیقی

نیمه دوم این خانواده کاتالوگ‌های بزرگ اجتماعی را هدف می‌گیرد.

pyprogarchives (Prog Archives)، pyjazzmusicarchives (Jazz Music Archives) — هر دو مستقیماً از مخزن‌های GitHub خود نصب می‌شوند نه از PyPI — و pyclassicalarchives (Classical Archives) شکلی تقریباً یکسان دارند: مرور فهرست A–Z، جست‌وجو بر اساس نام و دریافت یک صفحه کامل هنرمند یا آهنگساز با زندگی‌نامه، کشور و یک دیسکوگرافی امتیازدهی‌شده توسط اعضا. Prog و Jazz Archives از HTML اسکرپ می‌کنند؛ Classical Archives یک API عمومی JSON را دربرمی‌گیرد و آلبوم‌های یک آهنگساز و یک درخت آثار که به‌صورت بازگشتی مسطح شده را نمایان می‌کند. هر مدل، شناسه canonical پایدار سایت را از طریق to_external_ids_dict() حمل می‌کند، که دقیقاً همان چیزی است که برای ارجاع متقابل یک کاتالوگ به کاتالوگ دیگر نیاز دارید.

pymetal کلاینت ما برای Encyclopaedia Metallum، همان Metal Archives است — و بلندپروازانه‌ترین عضو این مجموعه. بیشتر اسکرپرها یک قطعه را به (id, title, band, album) مسطح می‌کنند. pymetal از دست دادن آنچه Metal Archives جدا نگه می‌دارد سر باز می‌زند: یک قطعه می‌تواند به چندین گروه اعتبار بدهد (اسپلیت‌ها، همکاری‌ها)، ترکیب اعضای یک گروه در طول زمان تکه‌تکه می‌شود و یک قطعه می‌تواند در بسیاری از انتشارها ظاهر شود (مجموعه‌ها، تجدید چاپ‌ها، تک‌آهنگ‌ها). هرکدام را به‌عنوان یک موجودیت درجه‌یک با کلید شناسه آرشیو مدل می‌کند، تا اسکرپ‌های مجدد idempotent باشند. سطح endpoint ها گسترده است — جست‌وجوی پیشرفته گروه/آلبوم/آهنگ، صفحات کامل انتشار با انتساب به‌ازای هر گروه در اسپلیت‌ها، ترکیب اعضای پارتیشن‌شده بر اساس وضعیت با بازه‌های تاریخ نقش، نقدها، پیشنهادها، لینک‌های خارجی و متن ترانه‌ها — همه به‌شکل مدل‌های Pydantic v2 که به‌صورت round-trip از میان JSON عبور می‌کنند.

فراتر از موسیقی، tutubo از YouTube و YouTube Music اسکرپ می‌کند و pymal پوشش‌دهنده MyAnimeList است — همان الگوهای متادیتای تایپ‌شده را به دسته‌های رسانه‌ای گسترده‌تر تعمیم می‌دهند. همه همان واژگان را ارائه می‌دهند تا یک مصرف‌کننده پایین‌دستی واحد بتواند همه‌چیز را به‌طور یکنواخت مدیریت کند.

ساخته‌شده برای دسترسیِ سازگار و کم‌حجم

این کلاینت‌ها تنها صفحات کاتالوگِ عمومی را با حجم درخواستِ پایین دریافت می‌کنند و پیش از اسکرپ کردن، robots.txt هر سایت را بررسی می‌کنند — برای اینکه این گام شناسایی چگونه کار می‌کند، به نوشته‌ی robots.txt و نقشه‌های سایت نگاه کنید. در سراسر این خانواده، لایه HTTP قابل‌جایگزینی است: به‌طور پیش‌فرض کلاینت‌ها از لایه انتقالی استفاده می‌کنند که دست‌دادنِ TLS آن با یک مرورگر واقعی مطابقت دارد (curl_cffi که با TLS/JA3 کروم مطابقت دارد)، پس یک کلاینتِ خوش‌رفتار توسط سامانه‌های تشخیصیِ تنظیم‌شده برای سوءاستفاده‌ی اسکریپت‌شده به‌اشتباه به‌عنوان خودکارسازیِ مخرب طبقه‌بندی نمی‌شود. دانشنامه‌های پشت Cloudflare می‌توانند علاوه بر این از طریق یک نمونه FlareSolverr برای داده‌های زنده مسیریابی شوند، یا به‌عنوان سازوکار پشتیبان از Wayback Machine در Internet Archive بخوانند. لایه parsing به‌طور عمدی مستقل از نحوه رسیدن HTML است، بنابراین همان کد فارغ از این‌که کدام لایه انتقال را انتخاب کنید کار می‌کند.

یک کاتالوگ موسیقی چندمنبعی

بازده واقعی زمانی رخ می‌دهد که دیگر این‌ها را به‌عنوان نه ابزار جداگانه نبینید. از آنجا که همه همان واژگان تایپ‌شده متادیتا را ارائه می‌دهند و همه شناسه‌های خارجی canonical را نمایان می‌کنند، می‌توانید یک هنرمند واحد را در Bandcamp، SoundCloud، دایرکتوری‌های رادیو و دانشنامه‌ها پخش کنید و سپس نتایج را در یک کاتالوگ منسجم واحد تا کنید — حذف‌تکرارشده بر اساس هویت، آگاه از مجوز و آماده برای تغذیه یک موتور پیشنهاد، یک سرور رسانه یا یک دیتاست پژوهشی.

هر یک از این کلاینت‌ها نرم‌افزار آزاد، قابل‌خودمیزبانی است و روی سخت‌افزار خودتان بدون نیاز به هیچ کلید API اجرا می‌شود. منبعی را که به آن اهمیت می‌دهید انتخاب کنید: اگر روی PyPI باشد pip install کنید، یا برای pyprogarchives و pyjazzmusicarchives که فقط روی GitHub هستند pip install git+https://github.com/TigreGotico/<repo> بزنید — و شروع به ساختن کنید.

همه اسکرپرها بر نشست‌های ترکیب‌پذیر و جایگزینِ مستقیمِ requests ما سوار هستند. کلاینت‌های استریم و رادیو، اسکیمای mediavocab را مستقیماً ارائه می‌دهند و هر کلاینت شناسه‌های خارجی canonical را نمایان می‌کند، تا متادیتای موسیقی با media-archivist — ایندکسر چندمنبعی و سرور متادیتای حذف‌کننده تکرار ما — یکپارچه شود.