使用Selenium Java检测页面链接均返回403状态码求助
嗨,我之前也碰到过一模一样的问题!这种情况基本是网站的反爬机制在识别Selenium的特征——毕竟默认的Selenium太容易被揪出来了。给你几个亲测有效的解决方案,挨个试试:
1. 伪装Selenium的核心特征,让它更像真实浏览器
很多网站会通过navigator.webdriver这个属性检测爬虫,默认Selenium会把它设为true,简直是明牌告诉网站“我是爬虫”。你可以通过JS修改这个属性:
((JavascriptExecutor) driver).executeScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
另外,记得把User-Agent设置成和你真实浏览器完全一致的字符串(可以在浏览器开发者工具的Network面板里复制):
ChromeOptions options = new ChromeOptions(); options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"); WebDriver driver = new ChromeDriver(options);
2. 用浏览器原生会话捕获请求,别单独发请求
你现在的方法应该是对每个链接单独发起请求,但哪怕带了Cookie,也可能遗漏了网站依赖的其他隐式验证信息(比如CSRF Token、会话关联的其他参数)。推荐用Chrome DevTools Protocol(CDP)直接在当前浏览器会话里捕获所有请求的状态码:
ChromeDriver driver = new ChromeDriver(); DevTools devTools = driver.getDevTools(); devTools.createSession(); // 启用网络监听 devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty())); // 监听响应事件,获取状态码 devTools.addListener(Network.responseReceived(), response -> { String targetUrl = response.getResponse().getUrl(); int statusCode = response.getResponse().getStatus(); System.out.println("链接: " + targetUrl + " 状态码: " + statusCode); }); // 访问目标页面,触发所有链接的加载(如果是动态加载的链接,可能需要模拟滚动或点击) driver.get(webPageUrl);
这种方式完全模拟用户浏览行为,状态码和你在浏览器里看到的会完全一致。
3. 检查是否遗漏了关键请求头
除了Cookie,网站可能还会验证Referer、Origin、Accept-Language这些请求头。你可以在浏览器Network面板里找到正常请求的所有头信息,确保在请求时全部带上(用CDP的话会自动继承当前会话的头,不用手动加)。
4. 给请求加随机延迟,避免触发限流
如果你的脚本遍历链接速度太快,很容易被网站判定为爬虫返回403。可以在每次请求/操作之间加个1-3秒的随机延迟:
Thread.sleep((long) (Math.random() * 2000 + 1000)); // 随机延迟1到3秒
5. 无头模式的额外配置
如果用了无头浏览器,一定要开启新版无头模式,并且禁用自动化特征检测:
ChromeOptions options = new ChromeOptions(); options.addArguments("--headless=new"); // 新版无头模式,和正常浏览器几乎无差别 options.addArguments("--disable-blink-features=AutomationControlled"); options.addArguments("--start-maximized");
如果以上方法还不行,建议把完整的getHttpResponseStatusCode方法贴出来,能更精准地排查问题。
内容的提问来源于stack exchange,提问作者Didit Setiawan

