Hana Celeste commited on
Commit
fcb5197
·
verified ·
1 Parent(s): 715605d

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +64 -52
main.py CHANGED
@@ -14,7 +14,6 @@ async def get_page(uid: str, fast_mode=False):
14
  '--no-sandbox',
15
  '--disable-setuid-sandbox',
16
  '--disable-dev-shm-usage',
17
- '--disable-accelerated-2d-canvas',
18
  '--disable-gpu'
19
  ])
20
  context = await browser.new_context(
@@ -23,21 +22,17 @@ async def get_page(uid: str, fast_mode=False):
23
  )
24
  page = await context.new_page()
25
 
26
- # CHẶN TỐI ĐA ĐỂ TĂNG TỐC BĂNG THÔNG
27
  async def block_waste(route):
28
  bad_types = ["media", "font", "other"]
29
  if fast_mode: bad_types.extend(["image", "stylesheet"])
30
-
31
- if route.request.resource_type in bad_types or "google" in route.request.url:
32
  await route.abort()
33
  else:
34
  await route.continue_()
35
 
36
  await page.route("**/*", block_waste)
37
-
38
- url = f"https://enka.network/u/{uid}/"
39
- # wait_until="commit" là nhanh nhất, bắt đầu ngay khi có phản hồi từ server
40
- await page.goto(url, wait_until="domcontentloaded", timeout=60000)
41
  return browser, page
42
 
43
  @app.get("/info")
@@ -45,51 +40,51 @@ async def info(uid: str):
45
  start_time = time.time()
46
  browser, page = await get_page(uid, fast_mode=True)
47
  try:
48
- # Thực hiện Click Namecard song song với việc lấy Data để tiết kiệm thời gian
49
- await page.click('button[data-icon="cards"]', timeout=3000).catch(lambda e: None)
 
 
 
 
50
 
51
  data = await page.evaluate("""
52
- async () => {
53
- const getPlayer = () => {
54
- const name = document.querySelector('.details h1')?.innerText;
55
- const signature = document.querySelector('.signature')?.innerText;
56
- const arText = document.querySelector('.ar')?.innerText || "";
57
- const stats = Array.from(document.querySelectorAll('tr.stat')).map(tr => {
58
- const style = tr.querySelector('td.icon')?.getAttribute('style') || "";
59
- const iconMatch = style.match(/url\\(["']?(.*?)["']?\\)/);
60
- return {
61
- value: tr.querySelector('td:first-child')?.innerText.trim(),
62
- label: tr.querySelector('td:last-child')?.innerText.trim(),
63
- icon: iconMatch ? "https://enka.network" + iconMatch[1].replace(/\\\\/g, "") : null
64
- };
65
- });
66
- const ncBg = document.querySelector('.Loda .bg')?.style.backgroundImage;
67
- const ncMatch = ncBg ? ncBg.match(/url\\(["']?(.*?)["']?\\)/) : null;
68
-
69
- return {
70
- name,
71
- signature,
72
- ar: arText.match(/AR\\s*(\\d+)/i)?.[1],
 
 
 
 
 
 
 
 
 
73
  wl: arText.match(/WL\\s*(\\d+)/i)?.[1],
74
  avatar: "https://enka.network" + document.querySelector('.avatar-icon img')?.getAttribute('src'),
75
  namecard: ncMatch ? "https://enka.network" + ncMatch[1] : null,
76
- stats
77
- };
 
78
  };
79
-
80
- const getChars = () => {
81
- return Array.from(document.querySelectorAll('.CharacterList .avatar')).map(el => {
82
- const style = el.querySelector('figure.chara')?.getAttribute('style') || "";
83
- const path = style.match(/url\\((.*)\\)/)?.[1].replace(/["']/g, "");
84
- return {
85
- name: path?.split('_').pop().split('.')[0],
86
- level: el.querySelector('.level')?.innerText,
87
- icon: "https://enka.network" + path
88
- };
89
- }).filter(i => i.name);
90
- };
91
-
92
- return { player: getPlayer(), characters: getChars() };
93
  }
94
  """)
95
 
@@ -106,17 +101,34 @@ async def generate(uid: str, char: str = None):
106
  try:
107
  if char:
108
  target = char.strip().capitalize()
109
- await page.click(f"//figure[contains(@style, '{target}')]", timeout=5000).catch(lambda e: None)
110
- await asyncio.sleep(0.8) # Giảm sleep xuống mức tối thiểu
 
 
111
 
112
  await page.click('button[data-icon="image"]')
113
- img_el = await page.wait_for_selector('.Loda img[src^="blob:"]', timeout=15000)
114
 
115
- img_base64 = await page.evaluate("async () => { const res = await fetch(document.querySelector('.Loda img').src); const blob = await res.blob(); return new Promise(r => { const rd = new FileReader(); rd.onloadend = () => r(rd.result.split(',')[1]); rd.readAsDataURL(blob); }); }")
 
 
 
 
 
 
 
 
 
 
 
116
 
117
  await browser.close()
118
- res = requests.post("https://api.imgbb.com/1/upload", data={"key": IMGBB_API_KEY, "image": img_base64}, timeout=15)
119
  return {"execution_time": f"{round(time.time() - start_time, 2)}s", "uid": uid, "card_url": res.json().get('data', {}).get('url')}
120
  except Exception as e:
121
  if 'browser' in locals(): await browser.close()
122
  return {"error": str(e)}
 
 
 
 
 
14
  '--no-sandbox',
15
  '--disable-setuid-sandbox',
16
  '--disable-dev-shm-usage',
 
17
  '--disable-gpu'
18
  ])
19
  context = await browser.new_context(
 
22
  )
23
  page = await context.new_page()
24
 
25
+ # CHẶN RÁC ĐỂ TĂNG TỐC
26
  async def block_waste(route):
27
  bad_types = ["media", "font", "other"]
28
  if fast_mode: bad_types.extend(["image", "stylesheet"])
29
+ if any(x in route.request.url for x in ["google", "analytics", "doubleclick"]):
 
30
  await route.abort()
31
  else:
32
  await route.continue_()
33
 
34
  await page.route("**/*", block_waste)
35
+ await page.goto(f"https://enka.network/u/{uid}/", wait_until="domcontentloaded", timeout=60000)
 
 
 
36
  return browser, page
37
 
38
  @app.get("/info")
 
40
  start_time = time.time()
41
  browser, page = await get_page(uid, fast_mode=True)
42
  try:
43
+ # CLICK NAMECARD (Dùng try/except thay cho .catch)
44
+ try:
45
+ await page.click('button[data-icon="cards"]', timeout=3000)
46
+ await page.wait_for_selector('.Loda .bg', timeout=3000)
47
+ except:
48
+ pass # Bỏ qua nếu không có namecard hoặc quá chậm
49
 
50
  data = await page.evaluate("""
51
+ () => {
52
+ const arText = document.querySelector('.ar')?.innerText || "";
53
+ const stats = Array.from(document.querySelectorAll('tr.stat')).map(tr => {
54
+ const style = tr.querySelector('td.icon')?.getAttribute('style') || "";
55
+ const iconMatch = style.match(/url\\(["']?(.*?)["']?\\)/);
56
+ return {
57
+ value: tr.querySelector('td:first-child')?.innerText.trim(),
58
+ label: tr.querySelector('td:last-child')?.innerText.trim(),
59
+ icon: iconMatch ? "https://enka.network" + iconMatch[1].replace(/\\\\/g, "") : null
60
+ };
61
+ });
62
+
63
+ const ncBg = document.querySelector('.Loda .bg')?.style.backgroundImage;
64
+ const ncMatch = ncBg ? ncBg.match(/url\\(["']?(.*?)["']?\\)/) : null;
65
+
66
+ const characters = Array.from(document.querySelectorAll('.CharacterList .avatar')).map(el => {
67
+ const style = el.querySelector('figure.chara')?.getAttribute('style') || "";
68
+ const path = style.match(/url\\((.*)\\)/)?.[1].replace(/["']/g, "");
69
+ return {
70
+ name: path?.split('_').pop().split('.')[0],
71
+ level: el.querySelector('.level')?.innerText,
72
+ icon: "https://enka.network" + path
73
+ };
74
+ }).filter(i => i.name);
75
+
76
+ return {
77
+ player: {
78
+ name: document.querySelector('.details h1')?.innerText,
79
+ signature: document.querySelector('.signature')?.innerText,
80
+ ar: arText.match(/AR\\s*(\\d+)/i)?.[1],
81
  wl: arText.match(/WL\\s*(\\d+)/i)?.[1],
82
  avatar: "https://enka.network" + document.querySelector('.avatar-icon img')?.getAttribute('src'),
83
  namecard: ncMatch ? "https://enka.network" + ncMatch[1] : null,
84
+ stats: stats
85
+ },
86
+ characters: characters
87
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
  """)
90
 
 
101
  try:
102
  if char:
103
  target = char.strip().capitalize()
104
+ try:
105
+ await page.click(f"//figure[contains(@style, '{target}')]", timeout=5000)
106
+ await asyncio.sleep(0.8)
107
+ except: pass
108
 
109
  await page.click('button[data-icon="image"]')
110
+ await page.wait_for_selector('.Loda img[src^="blob:"]', timeout=15000)
111
 
112
+ img_base64 = await page.evaluate("""
113
+ async () => {
114
+ const img = document.querySelector('.Loda img');
115
+ const res = await fetch(img.src);
116
+ const blob = await res.blob();
117
+ return new Promise(r => {
118
+ const rd = new FileReader();
119
+ rd.onloadend = () => r(rd.result.split(',')[1]);
120
+ rd.readAsDataURL(blob);
121
+ });
122
+ }
123
+ """)
124
 
125
  await browser.close()
126
+ res = requests.post("https://api.imgbb.com/1/upload", data={"key": IMGBB_API_KEY, "image": img_base64}, timeout=20)
127
  return {"execution_time": f"{round(time.time() - start_time, 2)}s", "uid": uid, "card_url": res.json().get('data', {}).get('url')}
128
  except Exception as e:
129
  if 'browser' in locals(): await browser.close()
130
  return {"error": str(e)}
131
+
132
+ @app.get("/")
133
+ def home():
134
+ return {"status": "Enka API Fixed & Running"}