prince1604 commited on
Commit
d92f150
·
1 Parent(s): 747f2d2

Fix crawl evasion: Add WAF block detection to Tier 1 fetch

Browse files
src/__pycache__/crawler.cpython-314.pyc CHANGED
Binary files a/src/__pycache__/crawler.cpython-314.pyc and b/src/__pycache__/crawler.cpython-314.pyc differ
 
src/crawler.py CHANGED
@@ -53,14 +53,21 @@ class Crawler:
53
  # Tier 1: curl_cffi
54
  content = self._fetch_http(url)
55
  if content:
56
- return content
 
 
 
 
57
 
58
  # Tier 2: Cloudscraper (Intermediate, handles JS challenges)
59
  logger.info(f"Tier 1 failed. Trying Cloudscraper info for {url}...")
60
  try:
61
  resp = self.scraper.get(url, timeout=10)
62
  if 200 <= resp.status_code < 300:
63
- return resp.text
 
 
 
64
  except Exception as e:
65
  logger.warning(f"Cloudscraper failed: {e}")
66
 
@@ -71,6 +78,34 @@ class Crawler:
71
 
72
  return None
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  def _fetch_http(self, url):
75
  """
76
  Fast HTTP fetch with aggressive timeouts and minimal retries.
 
53
  # Tier 1: curl_cffi
54
  content = self._fetch_http(url)
55
  if content:
56
+ # Validate content isn't a block page
57
+ if not self._is_blocked(content):
58
+ return content
59
+ else:
60
+ logger.warning(f"Tier 1 fetched blocked content for {url}. Escalating...")
61
 
62
  # Tier 2: Cloudscraper (Intermediate, handles JS challenges)
63
  logger.info(f"Tier 1 failed. Trying Cloudscraper info for {url}...")
64
  try:
65
  resp = self.scraper.get(url, timeout=10)
66
  if 200 <= resp.status_code < 300:
67
+ if not self._is_blocked(resp.text):
68
+ return resp.text
69
+ else:
70
+ logger.warning(f"Cloudscraper also blocked for {url}.")
71
  except Exception as e:
72
  logger.warning(f"Cloudscraper failed: {e}")
73
 
 
78
 
79
  return None
80
 
81
+ def _is_blocked(self, content):
82
+ """
83
+ Detects if the content is likely a WAF block page, CAPTCHA, or 'Just a moment'.
84
+ """
85
+ if not content or len(content) < 500:
86
+ return True # Too small, suspicious
87
+
88
+ lower_content = content.lower()
89
+ block_keywords = [
90
+ "just a moment...",
91
+ "enable javascript",
92
+ "verify you are human",
93
+ "access denied",
94
+ "cloudflare",
95
+ "captcha",
96
+ "security check",
97
+ "turn on javascript",
98
+ "challenge.js"
99
+ ]
100
+
101
+ if any(k in lower_content for k in block_keywords):
102
+ # Double check: sometimes legitimate pages mention these words.
103
+ # But usually, if it's < 5KB and has these words, it's a block.
104
+ if len(content) < 5000:
105
+ return True
106
+
107
+ return False
108
+
109
  def _fetch_http(self, url):
110
  """
111
  Fast HTTP fetch with aggressive timeouts and minimal retries.