使用Selenium爬取遭Cloudflare机器人检测,如何绕过?
绕过Cloudflare机器人检测的可行方案
针对你用Selenium爬取Udemy页面被Cloudflare拦截的问题,以下是几个实用的解决办法:
1. 使用undetected-chromedriver替代官方ChromeDriver
这个库专门针对Cloudflare等反爬机制做了优化,能自动隐藏Selenium的自动化特征。
首先安装库:
pip install undetected-chromedriver
修改你的代码,替换原有的webdriver初始化部分:
import undetected_chromedriver as uc def get_reviews(url): # 初始化undetected-chromedriver,默认会处理大部分检测 driver = uc.Chrome() try: driver.get(url) wait = WebDriverWait(driver, 60) # 延长等待时间给Cloudflare验证 # 先等待页面主体加载完成(Cloudflare验证通过后才会出现) wait.until(EC.presence_of_element_located((By.ID, "udemy"))) # 再等待评论容器加载 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "carousel-module--container--27wzs"))) response_text = driver.page_source soup = BeautifulSoup(response_text, 'html.parser') udemy_body = soup.find('body', {'id': 'udemy'}) if udemy_body: review_spans = udemy_body.find_all('span', class_='ud-text-md review--review-content-with-modal-trigger--vsRaS') reviews = [review_span.get_text(strip=True) for review_span in review_spans] print(reviews) else: logger.warning(f"Body element with id 'udemy' not found for {url}.") except Exception as e: logger.error(f"An error occurred for {url}: {e}") finally: driver.quit()
2. 手动完成Cloudflare人机验证(适合小量爬取)
如果是学术项目只需要爬取少量页面,可以在代码中加入足够长的等待时间,手动完成Cloudflare的滑块/验证码验证:
修改等待逻辑:
def get_reviews(url): driver = webdriver.Chrome(options=options) try: driver.get(url) # 提示用户完成验证 input("请完成页面上的Cloudflare验证,完成后按回车继续...") # 验证完成后等待页面加载 wait = WebDriverWait(driver, 30) wait.until(EC.presence_of_element_located((By.ID, "udemy"))) wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "carousel-module--container--27wzs"))) # 后续解析逻辑不变... except Exception as e: logger.error(f"An error occurred for {url}: {e}") finally: driver.quit()
3. 增强用户行为模拟
Cloudflare会检测异常的访问模式,模拟真实用户的操作可以降低被识别的概率:
- 加入随机延迟,避免固定等待时间
- 模拟页面滚动、鼠标移动
- 避免直接跳转到目标页面,先访问Udemy首页再导航到课程页
修改后的代码示例:
import random from selenium.webdriver.common.action_chains import ActionChains def get_reviews(url): driver = webdriver.Chrome(options=options) try: # 先访问Udemy首页,模拟正常浏览路径 driver.get("https://www.udemy.com/") sleep(random.uniform(2, 5)) # 随机延迟2-5秒 # 导航到目标课程页 driver.get(url) wait = WebDriverWait(driver, 60) # 模拟鼠标移动到页面随机位置 actions = ActionChains(driver) actions.move_by_offset(random.randint(100, 500), random.randint(100, 500)).perform() sleep(random.uniform(1, 3)) # 模拟滚动页面 driver.execute_script("window.scrollTo(0, document.body.scrollHeight/2);") sleep(random.uniform(1, 3)) # 等待页面加载完成 wait.until(EC.presence_of_element_located((By.ID, "udemy"))) wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "carousel-module--container--27wzs"))) # 后续解析逻辑不变... except Exception as e: logger.error(f"An error occurred for {url}: {e}") finally: driver.quit()
4. 额外隐藏自动化特征
在原有Options基础上,添加更多隐藏Selenium痕迹的配置:
options = Options() options.add_argument("--window-size=1920,1080") options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") # 使用最新版UA options.add_argument("--disable-gpu") options.add_argument("--ignore-certificate-errors") options.add_experimental_option("excludeSwitches", ["enable-automation", "enable-logging"]) options.add_experimental_option('useAutomationExtension', False) # 禁用Blink运行时的自动化控制 options.add_argument("--disable-blink-features=AutomationControlled") driver = webdriver.Chrome(options=options) # 强制修改navigator.webdriver属性 driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
这些方案可以单独或组合使用,其中undetected-chromedriver是最省心的方案,适合批量爬取;手动验证适合小量学术研究需求。
内容的提问来源于stack exchange,提问作者Katsu
相关产品推荐
相关产品推荐

