feat: Add new GUI effects view and numerous image assets.
This commit is contained in:
170
test_scraper.py
170
test_scraper.py
@@ -1,87 +1,111 @@
|
||||
"""Quick test of the fixed level navigation"""
|
||||
|
||||
import sqlite3
|
||||
import os
|
||||
from playwright.sync_api import sync_playwright
|
||||
import sys
|
||||
|
||||
# Add project root to path
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
URL = "https://gametora.com/umamusume/supports/30022-mejiro-mcqueen"
|
||||
|
||||
def test_levels():
|
||||
print("Testing fixed level navigation...")
|
||||
|
||||
def test_scrape_events(url):
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
page = browser.new_page()
|
||||
|
||||
page.goto(URL, timeout=60000)
|
||||
page.wait_for_load_state("networkidle")
|
||||
print(f"Testing URL: {url}")
|
||||
page.goto(url)
|
||||
page.wait_for_timeout(2000)
|
||||
|
||||
for target in [1, 25, 40, 50]:
|
||||
actual = page.evaluate("""
|
||||
async (targetLevel) => {
|
||||
const getLevel = () => {
|
||||
const el = Array.from(document.querySelectorAll('div')).find(d =>
|
||||
d.textContent.trim().startsWith('Level ') && d.children.length === 0
|
||||
);
|
||||
if (!el) {
|
||||
const text = document.body.innerText;
|
||||
const match = text.match(/Level\\s*(\\d+)/i);
|
||||
return match ? parseInt(match[1]) : 30;
|
||||
}
|
||||
return parseInt(el.textContent.replace('Level ', '').trim());
|
||||
};
|
||||
|
||||
const clickButton = (text) => {
|
||||
const btns = Array.from(document.querySelectorAll('div'));
|
||||
const btn = btns.find(d => d.textContent.trim() === text && d.children.length === 0);
|
||||
if (btn) {
|
||||
btn.click();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
let currentLevel = getLevel();
|
||||
|
||||
while (currentLevel !== targetLevel) {
|
||||
let btnText;
|
||||
if (currentLevel > targetLevel) {
|
||||
const diff = currentLevel - targetLevel;
|
||||
btnText = diff >= 5 ? '-5' : '-1';
|
||||
} else {
|
||||
const diff = targetLevel - currentLevel;
|
||||
btnText = diff >= 5 ? '+5' : '+1';
|
||||
}
|
||||
|
||||
if (!clickButton(btnText)) break;
|
||||
|
||||
const startLevel = currentLevel;
|
||||
let start = Date.now();
|
||||
while (Date.now() - start < 1000) {
|
||||
await new Promise(r => setTimeout(r, 50));
|
||||
const newLevel = getLevel();
|
||||
if (newLevel !== startLevel) {
|
||||
currentLevel = newLevel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentLevel === startLevel) break;
|
||||
# 1. First, build a map of skills from the 'Skills from events' summary section
|
||||
skill_rarity_map = page.evaluate("""
|
||||
() => {
|
||||
const map = {};
|
||||
const sections = Array.from(document.querySelectorAll('div')).filter(d => d.innerText.includes('Skills from events'));
|
||||
if (sections.length === 0) return { error: 'No Skills from events section' };
|
||||
|
||||
const containers = sections[0].parentElement.querySelectorAll('div[class*="sc-"]');
|
||||
containers.forEach(c => {
|
||||
const nameNode = c.querySelector('div[font-weight="bold"], span[font-weight="bold"], b');
|
||||
const name = nameNode ? nameNode.innerText.trim() : c.innerText.split('\\n')[0].trim();
|
||||
if (name && name.length > 2) {
|
||||
const isGold = c.className.includes('kkspcu') ||
|
||||
window.getComputedStyle(c).backgroundColor.includes('rgb(255, 193, 7)') ||
|
||||
c.innerText.includes('✨');
|
||||
map[name] = isGold;
|
||||
}
|
||||
|
||||
await new Promise(r => setTimeout(r, 200));
|
||||
return getLevel();
|
||||
}
|
||||
""", target)
|
||||
|
||||
status = "✓" if actual == target else "✗"
|
||||
print(f"Target: {target} -> Actual: {actual} {status}")
|
||||
});
|
||||
return map;
|
||||
}
|
||||
""")
|
||||
print(f"Skill Rarity Map: {skill_rarity_map}")
|
||||
|
||||
# 2. Scrape ONLY the LAST chain event (Golden Perk) with OR options
|
||||
golden_perk_data = page.evaluate("""
|
||||
async () => {
|
||||
const getChainEventButtons = () => {
|
||||
const buttons = [];
|
||||
const headers = Array.from(document.querySelectorAll('div, h2, h3, span')).filter(el =>
|
||||
el.innerText.includes('Chain Events')
|
||||
);
|
||||
|
||||
headers.forEach(header => {
|
||||
const container = header.parentElement;
|
||||
if (container) {
|
||||
const btns = Array.from(container.querySelectorAll('button'));
|
||||
btns.forEach(btn => {
|
||||
const text = btn.innerText.trim();
|
||||
const isVisible = btn.offsetWidth > 0;
|
||||
if (isVisible && text && text.includes('>') && !text.includes('Events')) {
|
||||
buttons.push(btn);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return buttons;
|
||||
};
|
||||
|
||||
const buttons = getChainEventButtons();
|
||||
if (buttons.length === 0) return { error: 'No chain event buttons found' };
|
||||
|
||||
let goldenPerkButton = null;
|
||||
let maxArrows = 0;
|
||||
for (const btn of buttons) {
|
||||
const text = btn.innerText.trim();
|
||||
const arrowCount = (text.match(/>/g) || []).length;
|
||||
if (arrowCount > maxArrows) {
|
||||
maxArrows = arrowCount;
|
||||
goldenPerkButton = btn;
|
||||
}
|
||||
}
|
||||
|
||||
if (!goldenPerkButton) return { error: 'No golden perk button identified' };
|
||||
|
||||
const eventName = goldenPerkButton.innerText.trim();
|
||||
goldenPerkButton.click();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
const popovers = Array.from(document.querySelectorAll('div')).filter(d =>
|
||||
d.innerText.includes(eventName) &&
|
||||
window.getComputedStyle(d).zIndex > 50
|
||||
);
|
||||
|
||||
if (popovers.length === 0) return { error: 'Popover not found', eventName: eventName };
|
||||
|
||||
const pop = popovers[popovers.length - 1];
|
||||
const skillLinks = Array.from(pop.querySelectorAll('span, a')).filter(el =>
|
||||
el.innerText.length > 2 &&
|
||||
(window.getComputedStyle(el).color === 'rgb(102, 107, 255)' ||
|
||||
el.className.includes('linkcolor'))
|
||||
);
|
||||
|
||||
return {
|
||||
name: eventName,
|
||||
skills: skillLinks.map(l => l.innerText.trim())
|
||||
};
|
||||
}
|
||||
""")
|
||||
print(f"Golden Perk Data: {golden_perk_data}")
|
||||
browser.close()
|
||||
|
||||
print("Done!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_levels()
|
||||
# Test with Gentildonna (verified URL from subagent)
|
||||
test_scrape_events("https://gametora.com/umamusume/supports/30186-gentildonna")
|
||||
|
||||
Reference in New Issue
Block a user