Advertisement
Some_Aspy

Extract level data from Arcane

Apr 17th, 2025
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 5.92 KB | Source Code | 0 0
  1. /**
  2.  * Parses numeric strings that might contain 'K' (thousands) or 'M' (millions).
  3.  * Example: "232.7K" => 232700, "1.5M" => 1500000, "500" => 500
  4.  * @param {string} valueStr The string value to parse.
  5.  * @returns {number} The parsed numeric value. Returns 0 if parsing fails or input is '-'.
  6.  */
  7. function parseNumericValue(valueStr) {
  8.     if (!valueStr || typeof valueStr !== 'string') {
  9.         return 0;
  10.     }
  11.     const cleanedStr = valueStr.trim().toUpperCase();
  12.     // Handle cases like '-' which mean zero/not applicable
  13.     if (cleanedStr === '-') {
  14.         return 0;
  15.     }
  16.  
  17.     let multiplier = 1;
  18.     let numPart = cleanedStr;
  19.  
  20.     if (cleanedStr.endsWith('K')) {
  21.         multiplier = 1000;
  22.         numPart = cleanedStr.slice(0, -1);
  23.     } else if (cleanedStr.endsWith('M')) {
  24.         multiplier = 1000000;
  25.         numPart = cleanedStr.slice(0, -1);
  26.     }
  27.  
  28.     const num = parseFloat(numPart);
  29.     if (isNaN(num)) {
  30.         return 0; // Return 0 if it's not a valid number after processing
  31.     }
  32.  
  33.     return Math.round(num * multiplier); // Use Math.round for cases like 232.7K
  34. }
  35.  
  36.  
  37. /**
  38.  * Parses the HTML structure containing user level data and transforms it
  39.  * into the specified JSON format.
  40.  * Assumes the HTML is present in the current document.
  41.  */
  42. function extractLevelData() {
  43.     // Find all the user data boxes
  44.     const userBoxes = document.querySelectorAll('.box.box-hover');
  45.  
  46.     const levels = [];
  47.  
  48.     userBoxes.forEach(box => {
  49.         try {
  50.             // --- Extract Avatar and User ID ---
  51.             const imgElement = box.querySelector('figure.image img');
  52.             let avatar = null;
  53.             let userId = null;
  54.             if (imgElement && imgElement.src) {
  55.                 const src = imgElement.src;
  56.                 const avatarMatch = src.match(/avatars\/(\d+)\/([a-f0-9_]+)\.png/);
  57.                 if (avatarMatch) {
  58.                     userId = avatarMatch[1];
  59.                     avatar = avatarMatch[2];
  60.                 } else {
  61.                     // Try extracting userId from onerror attribute if it's a default avatar
  62.                     const onerrorAttr = imgElement.getAttribute('onerror');
  63.                     if (onerrorAttr) {
  64.                         // Attempt to find a user ID within the onerror string
  65.                         // This is less reliable and depends on the exact string format
  66.                         const userIdMatch = onerrorAttr.match(/avatars\/(\d+)/); // Simpler regex attempt
  67.                         if (userIdMatch && userIdMatch[1]) {
  68.                             // Check if it's just a placeholder like '1' vs a real ID
  69.                             if (userIdMatch[1].length > 5) { // Assume real IDs are longer
  70.                                 userId = userIdMatch[1];
  71.                             }
  72.                         }
  73.                     }
  74.                     avatar = null; // Default avatar
  75.                 }
  76.             }
  77.  
  78.             // --- Extract Tag (Username) ---
  79.             const tagElement = box.querySelector('p.has-text-white.is-size-5.has-text-weight-semibold:not([style*="min-width"])');
  80.             let tag = null;
  81.             if (tagElement && tagElement.textContent.startsWith('@')) {
  82.                 tag = tagElement.textContent.substring(1);
  83.             }
  84.  
  85.             // --- Extract Stats (Level, XP, MessageCount) by Order ---
  86.             // Select all potential stat <p> elements within the flex container THAT HAVE a min-width style
  87.             const statsElements = box.querySelectorAll('div[style*="display: flex"] > p.has-text-white.is-size-5.has-text-weight-semibold[style*="min-width"]');
  88.  
  89.             let level = 0;
  90.             let xp = 0;
  91.             let messageCount = 0;
  92.  
  93.             // Assign based on index position:
  94.             // Index 0: Level
  95.             if (statsElements.length > 0) {
  96.                 level = parseInt(statsElements[0].textContent.trim(), 10) || 0; // Level is usually an integer
  97.             }
  98.             // Index 1: XP
  99.             if (statsElements.length > 1) {
  100.                 xp = parseNumericValue(statsElements[1].textContent.trim());
  101.             }
  102.             // Index 2: Message Count
  103.             if (statsElements.length > 2) {
  104.                 messageCount = parseNumericValue(statsElements[2].textContent.trim());
  105.             }
  106.  
  107.             // --- Construct Level Object ---
  108.             // Only add if we successfully found a userId and tag
  109.             if (userId && tag) {
  110.                 levels.push({
  111.                     avatar: avatar,
  112.                     level: level,
  113.                     messageCount: messageCount, // Correctly assigned separate value
  114.                     tag: tag,
  115.                     userId: userId,
  116.                     xp: xp // Correctly assigned separate value
  117.                 });
  118.             } else {
  119.                 // Attempt to find userId from tag if missing from image (less common)
  120.                 // Requires a mapping or external lookup usually, cannot be done from HTML alone reliably.
  121.                 // Log a warning if critical info is missing.
  122.                 if (!userId) console.warn("Missing userId for tag:", tag, box);
  123.                 if (!tag) console.warn("Missing tag for box:", box);
  124.                 // console.warn("Could not extract required data (userId or tag) for box:", box);
  125.             }
  126.  
  127.         } catch (error) {
  128.             console.error("Error processing user box:", error, box);
  129.         }
  130.     });
  131.  
  132.     // --- Construct Final Export Object ---
  133.     const exportData = {
  134.         levels: levels
  135.     };
  136.  
  137.     // --- Output JSON ---
  138.     console.log(JSON.stringify(exportData, null, 2)); // Pretty print JSON
  139.     return exportData; // Return the data structure
  140. }
  141.  
  142. // --- Run the function ---
  143. // Make sure the HTML content is loaded in the document before calling this.
  144. // You would typically run this in the browser's developer console
  145. // on the page displaying the leaderboard HTML.
  146. extractLevelData();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement