使用HtmlUnit 2.47.1加载Twitter搜索页时JS异常无法获取推文
HtmlUnit加载Twitter搜索页未渲染推文的解决方案
核心原因
你当前拿不到推文内容,本质不是Js等待时间不够,是HtmlUnit默认的环境配置太容易被Twitter的前端安全策略识别,前端检测到非真实浏览器环境后,根本不会加载真实的推文数据接口,返回的只是页面空壳模板。
可直接调整的代码细节
- 替换默认的WebClient构造逻辑,匹配现代Chrome的浏览器版本,避免旧版浏览器指纹被直接拦截:
将原代码中new WebClient()替换为:// 指定模拟最新Chrome的环境 try (final WebClient webClient = new WebClient(BrowserVersion.CHROME)) { - 调整Js等待的逻辑顺序:
你现在的逻辑是请求页面完成后才触发后台Js等待,很多异步接口的请求还没发出,等再久也拉不到数据。正确顺序是先把Js相关配置全部放在getPage()之前完成,再发起请求,请求后延长等待时长:// 所有配置放在getPage之前 webClient.getOptions().setThrowExceptionOnScriptError(false); webClient.getOptions().setCssEnabled(false); webClient.getOptions().setUseInsecureSSL(true); webClient.getOptions().setJavaScriptEnabled(true); webClient.getOptions().setTimeout(30000); HtmlPage page = webClient.getPage(url_web); // 延长Js等待时间到30秒 webClient.waitForBackgroundJavaScript(30000); // 触发页面滚动,Twitter是懒加载机制,不滚动不会加载推文 page.executeJavaScript("window.scrollTo(0, document.body.scrollHeight)"); webClient.waitForBackgroundJavaScript(5000); System.out.println(page.asXml()); - 补充基础请求头,模拟真实浏览器的请求特征:
在WebClient初始化后加入:webClient.addRequestHeader("Accept-Language", "en-US,en;q=0.9"); webClient.addRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
实际使用提醒
- 初期调试不要直接把所有日志设为OFF,保留Js执行的错误日志,可以快速定位到前端抛出的环境检测报错
- 即使把上述配置全部调优,Twitter对未登录的爬虫请求风控非常严格,多次请求后大概率会被强制跳转到登录页面,未登录状态下拿不到完整搜索结果属于正常现象,HtmlUnit本身不具备绕过登录墙的能力
内容的提问来源于stack exchange,提问作者Charles P.
相关产品推荐
相关产品推荐

