Muttered3 commited on
Commit
d142137
·
verified ·
1 Parent(s): 623fb8a

Update scraper.py

Browse files
Files changed (1) hide show
  1. scraper.py +45 -47
scraper.py CHANGED
@@ -1,57 +1,55 @@
1
  import asyncio
2
  import random
3
- import aiohttp
4
-
5
- USER_AGENTS = [
6
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0 Safari/537.36",
7
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 Safari/605.1.15",
8
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/123.0 Safari/537.36",
9
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0"
10
- ]
11
 
12
  async def check_fragment(word: str) -> str:
13
  url = f"https://fragment.com/username/{word}"
14
 
15
- async with aiohttp.ClientSession() as session:
16
- for _ in range(6):
17
- for attempt in range(3):
18
- headers = {"User-Agent": random.choice(USER_AGENTS)}
19
- try:
20
- async with session.get(url, headers=headers, allow_redirects=True, timeout=15) as resp:
21
- if resp.status == 429:
22
- wait = (2 ** attempt * 3) + random.uniform(1, 3)
23
- await asyncio.sleep(wait)
24
- continue
25
-
26
- if resp.status == 200:
27
- html = await resp.text()
28
- await asyncio.sleep(random.uniform(0.15, 0.6))
29
-
30
- if "tm-status-avail" in html:
31
- return "AVAILABLE"
32
-
33
- if "tm-status-taken" in html:
34
- if "On auction" in html or "tm-section-subscribe" in html:
35
- return "ON_AUCTION"
36
- if "For sale" in html:
37
- return "FOR_SALE"
38
- # CRITICAL FIX: Looks for the specific sold text, avoiding the nav bar
39
- if ">Sold for" in html or ">Sold at" in html or 'class="tm-status-text">Sold' in html:
40
- return "SOLD"
41
- return "TAKEN"
42
-
43
- if "tm-status-unavail" in html:
44
- return "UNAVAILABLE"
 
45
 
46
- # Fallbacks
47
- if "Available" in html: return "AVAILABLE"
48
- if "Taken" in html: return "TAKEN"
49
-
50
- return "UNAVAILABLE"
51
-
52
- except Exception:
53
- pass
 
 
 
 
54
 
55
- await asyncio.sleep(random.uniform(0.8, 2.0))
56
 
57
  return "UNAVAILABLE"
 
1
  import asyncio
2
  import random
3
+ from curl_cffi.requests import AsyncSession
 
 
 
 
 
 
 
4
 
5
  async def check_fragment(word: str) -> str:
6
  url = f"https://fragment.com/username/{word}"
7
 
8
+ # Impersonates a real Chrome browser to bypass Cloudflare
9
+ async with AsyncSession(impersonate="chrome110") as session:
10
+ for _ in range(4):
11
+ try:
12
+ resp = await session.get(url, timeout=15)
13
+
14
+ # Wait out rate limits
15
+ if resp.status_code in [429, 403]:
16
+ await asyncio.sleep(random.uniform(2, 5))
17
+ continue
18
+
19
+ if resp.status_code == 200:
20
+ html = resp.text
21
+
22
+ # Double-check if Cloudflare intercepted the page anyway
23
+ if "Just a moment..." in html or "Cloudflare" in html:
24
+ await asyncio.sleep(random.uniform(3, 6))
25
+ continue
26
+
27
+ await asyncio.sleep(random.uniform(0.15, 0.6))
28
+
29
+ # --- HTML PARSER ---
30
+ if "tm-status-avail" in html: return "AVAILABLE"
31
+
32
+ if "tm-status-taken" in html:
33
+ if "On auction" in html or "tm-section-subscribe" in html: return "ON_AUCTION"
34
+ if "For sale" in html: return "FOR_SALE"
35
+ if ">Sold for" in html or ">Sold at" in html or 'class="tm-status-text">Sold' in html: return "SOLD"
36
+ return "TAKEN"
37
+
38
+ if "tm-status-unavail" in html: return "UNAVAILABLE"
39
 
40
+ # Fallbacks
41
+ if "Available" in html: return "AVAILABLE"
42
+ if "Taken" in html: return "TAKEN"
43
+
44
+ # If Fragment redirects to the search page, the word is usually available to claim
45
+ if "/?query=" in str(resp.url):
46
+ return "AVAILABLE"
47
+
48
+ return "UNAVAILABLE"
49
+
50
+ except Exception:
51
+ pass
52
 
53
+ await asyncio.sleep(random.uniform(1.0, 2.0))
54
 
55
  return "UNAVAILABLE"