טיפ פייתון: הרצת קוד JavaScript עם js2py

11/07/2023

המודול js2py הוא סוג של קסם - הוא לוקח קוד JavaScript ומתרגם אותו לפייתון, כך שאנחנו יכולים להפעיל קוד ולהתממשק עם התוצאה מתוך הפייתון שלנו. אני יודע רוב הזמן כולם רוצים לכתוב פייתון ולקמפל אותו ל JavaScript כדי שלא נצטרך לכתוב JavaScript אבל פה ה Use Case שונה.

המודול עוזר לפרויקטי Web Scraping או בדיקות, כשאנחנו לא רוצים או צריכים להפעיל סלניום מלא ובסך הכל רוצים לראות שה JavaScript עבד מספיק טוב או לקבל ממנו מידע. בהרבה אתרים יש קובץ JavaScript שמתאר כל מיני אופציות של האתר, לדוגמה באתר של dramatiq יש קובץ JavaScript שנראה כך:

var DOCUMENTATION_OPTIONS = {
    URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
    VERSION: '1.14.2',
    LANGUAGE: 'en',
    COLLAPSE_INDEX: false,
    BUILDER: 'html',
    FILE_SUFFIX: '.html',
    LINK_SUFFIX: '.html',
    HAS_SOURCE: true,
    SOURCELINK_SUFFIX: '.txt',
    NAVIGATION_WITH_KEYS: false,
    SHOW_SEARCH_SUMMARY: true,
    ENABLE_SEARCH_SHORTCUTS: true,
};

מה אם אני רוצה להשתמש במידע הזה מקוד פייתון שבודק את האתר או שמושך ממנו מידע? כן אני יכול לפרסר את הטקסט, אבל לא יהיה יותר קל פשוט להריץ את הקוד ולקחת את האוביקט בתור Dictionary? מסתבר שעם js2py זה מאוד פשוט:

code = requests.get('https://dramatiq.io/_static/documentation_options.js').text
ctx = js2py.EvalJs()
ctx.execute("document = {getElementById() { return {getAttribute() { return null }}}}")
ctx.execute(code)
print(ctx.DOCUMENTATION_OPTIONS)

data = ctx.DOCUMENTATION_OPTIONS.to_dict()
print(len(data))

התוכנית תדפיס את האוביקט בתור מילון של פייתון ואחר כך את מספר המפתחות שבו.

וכן החיסרון הברור בגישה זו הוא שאין לנו גישה ל APIs של הדפדפן לדוגמה ל Document, או לקבצי js שהיישום שעובדים עליו טוען גלובאלית. ועדיין אם אתם מוכנים לכתוב כמה mock-ים שימוש ב js2py יכול לחסוך עבודת תרגום כשצריך לשלב בין שתי השפות.