Spaces:
Paused
Paused
Update scraper.py
Browse files- scraper.py +14 -7
scraper.py
CHANGED
|
@@ -24,7 +24,8 @@ _rate_limited_until = 0.0
|
|
| 24 |
async def _get_valid_api_hash(proxy_url: str = None) -> str:
|
| 25 |
"""
|
| 26 |
Ensures a singular valid session context hash token is distributed across
|
| 27 |
-
all background threads simultaneously,
|
|
|
|
| 28 |
"""
|
| 29 |
global _global_api_hash, _hash_fetched_at
|
| 30 |
|
|
@@ -34,6 +35,11 @@ async def _get_valid_api_hash(proxy_url: str = None) -> str:
|
|
| 34 |
if _global_api_hash and (now - _hash_fetched_at < 900):
|
| 35 |
return _global_api_hash
|
| 36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
headers = {
|
| 38 |
"User-Agent": random.choice(USER_AGENTS),
|
| 39 |
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
@@ -45,7 +51,8 @@ async def _get_valid_api_hash(proxy_url: str = None) -> str:
|
|
| 45 |
try:
|
| 46 |
timeout = aiohttp.ClientTimeout(total=10)
|
| 47 |
async with aiohttp.ClientSession(timeout=timeout) as session:
|
| 48 |
-
|
|
|
|
| 49 |
html = await resp.text()
|
| 50 |
|
| 51 |
# Target matching layout configurations capturing nested App.init configurations
|
|
@@ -58,10 +65,10 @@ async def _get_valid_api_hash(proxy_url: str = None) -> str:
|
|
| 58 |
if match:
|
| 59 |
_global_api_hash = match.group(1)
|
| 60 |
_hash_fetched_at = now
|
| 61 |
-
log.info(f"π Successfully Stabilized Global API Hash Token: {_global_api_hash}")
|
| 62 |
return _global_api_hash
|
| 63 |
else:
|
| 64 |
-
log.error("β Token extraction fault. DOM format structure layout changed.")
|
| 65 |
with open("token_dom_error.log", "w", encoding="utf-8") as f:
|
| 66 |
f.write(html[:2000])
|
| 67 |
|
|
@@ -73,7 +80,7 @@ async def _get_valid_api_hash(proxy_url: str = None) -> str:
|
|
| 73 |
async def check_fragment(word: str, proxy_url: str = None) -> str:
|
| 74 |
"""
|
| 75 |
Connects directly to Fragment's internal AJAX endpoint using XMLHttpRequest signatures,
|
| 76 |
-
bypassing
|
| 77 |
"""
|
| 78 |
global _rate_limited_until
|
| 79 |
word = word.strip().replace("@", "").lower()
|
|
@@ -120,7 +127,7 @@ async def check_fragment(word: str, proxy_url: str = None) -> str:
|
|
| 120 |
response_json = await resp.json()
|
| 121 |
|
| 122 |
if not response_json.get("ok"):
|
| 123 |
-
#
|
| 124 |
global _global_api_hash
|
| 125 |
_global_api_hash = None
|
| 126 |
continue
|
|
@@ -148,7 +155,7 @@ async def check_fragment(word: str, proxy_url: str = None) -> str:
|
|
| 148 |
return s.upper()
|
| 149 |
|
| 150 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 151 |
-
# ENGINE 2: GLOBAL
|
| 152 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 153 |
fallback_text = clean_html.lower()
|
| 154 |
if "on auction" in fallback_text: return "ON_AUCTION"
|
|
|
|
| 24 |
async def _get_valid_api_hash(proxy_url: str = None) -> str:
|
| 25 |
"""
|
| 26 |
Ensures a singular valid session context hash token is distributed across
|
| 27 |
+
all background threads simultaneously, utilizing proxy routing to bypass
|
| 28 |
+
initial Cloudflare blocks on the server IP range.
|
| 29 |
"""
|
| 30 |
global _global_api_hash, _hash_fetched_at
|
| 31 |
|
|
|
|
| 35 |
if _global_api_hash and (now - _hash_fetched_at < 900):
|
| 36 |
return _global_api_hash
|
| 37 |
|
| 38 |
+
# Force proxy utilization on handshake layer to mask server footprint
|
| 39 |
+
active_proxy = proxy_url
|
| 40 |
+
if not active_proxy and state.proxies:
|
| 41 |
+
active_proxy = random.choice(state.proxies)
|
| 42 |
+
|
| 43 |
headers = {
|
| 44 |
"User-Agent": random.choice(USER_AGENTS),
|
| 45 |
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
|
|
| 51 |
try:
|
| 52 |
timeout = aiohttp.ClientTimeout(total=10)
|
| 53 |
async with aiohttp.ClientSession(timeout=timeout) as session:
|
| 54 |
+
# Route the home page request through the active proxy tunnel
|
| 55 |
+
async with session.get("https://fragment.com/", headers=headers, proxy=active_proxy, allow_redirects=True) as resp:
|
| 56 |
html = await resp.text()
|
| 57 |
|
| 58 |
# Target matching layout configurations capturing nested App.init configurations
|
|
|
|
| 65 |
if match:
|
| 66 |
_global_api_hash = match.group(1)
|
| 67 |
_hash_fetched_at = now
|
| 68 |
+
log.info(f"π Successfully Stabilized Global API Hash Token: {_global_api_hash} (via Proxy)")
|
| 69 |
return _global_api_hash
|
| 70 |
else:
|
| 71 |
+
log.error("β Token extraction fault. DOM format structure layout changed or proxy blocked.")
|
| 72 |
with open("token_dom_error.log", "w", encoding="utf-8") as f:
|
| 73 |
f.write(html[:2000])
|
| 74 |
|
|
|
|
| 80 |
async def check_fragment(word: str, proxy_url: str = None) -> str:
|
| 81 |
"""
|
| 82 |
Connects directly to Fragment's internal AJAX endpoint using XMLHttpRequest signatures,
|
| 83 |
+
bypassing front-end web layout redirection problems entirely.
|
| 84 |
"""
|
| 85 |
global _rate_limited_until
|
| 86 |
word = word.strip().replace("@", "").lower()
|
|
|
|
| 127 |
response_json = await resp.json()
|
| 128 |
|
| 129 |
if not response_json.get("ok"):
|
| 130 |
+
# Force token reload sequence if current register gets dropped by endpoint engine
|
| 131 |
global _global_api_hash
|
| 132 |
_global_api_hash = None
|
| 133 |
continue
|
|
|
|
| 155 |
return s.upper()
|
| 156 |
|
| 157 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 158 |
+
# ENGINE 2: GLOBAL FALLBACK LAYER MATCHING
|
| 159 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 160 |
fallback_text = clean_html.lower()
|
| 161 |
if "on auction" in fallback_text: return "ON_AUCTION"
|