Java代码与IE11解析Bing搜索页面的内容差异问询
这种差异本质上是Bing针对不同请求的上下文返回了不同的HTML内容,具体原因主要有这几点:
1. User-Agent 识别差异
IE11发送请求时会带上自己专属的User-Agent头,比如:
Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko
而Java代码默认发送HTTP请求时,用的是类似Java/1.8.0_xxx这类标识,Bing的服务器识别到这不是标准浏览器请求后,会返回简化、截断的内容(可能是为了反爬,或者针对非浏览器客户端做的内容适配)。
2. 请求头不完整
浏览器发送请求时会附带一堆标准头(比如Accept、Accept-Language、Accept-Encoding等),这些头告诉服务器客户端能接受的内容类型、语言、编码格式。Java默认的HTTP请求往往只带很少的头,Bing可能因为头信息不全,返回了非预期的简化版页面。
3. 动态内容渲染(可能性较低)
虽然你在IE11里看到的是完整的源码,但如果Bing部分内容是通过JavaScript动态加载的,那Java普通HTTP请求拿到的只是初始HTML框架,后续动态渲染的内容不会包含在内——不过你说IE里看的是页面源码(而非开发者工具的Elements面板),所以这种情况概率不高,但也可以排查下。
针对上面的原因,按优先级来处理:
1. 模拟浏览器的请求头
在Java的HTTP请求中,完全照搬IE11的请求头,核心是设置正确的User-Agent,同时补充其他必要的头。举个用HttpURLConnection的例子:
URL url = new URL("https://www.bing.com/search?q=vevo+USIV30300367"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置IE11的User-Agent conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko"); // 补充其他常见头 conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); conn.setRequestProperty("Connection", "keep-alive"); // 后续读取响应内容 BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; StringBuilder content = new StringBuilder(); while ((inputLine = in.readLine()) != null) { content.append(inputLine); } in.close(); conn.disconnect();
2. 使用无头浏览器渲染动态内容
如果上面的方法还是拿不到完整内容,说明页面有JS动态渲染逻辑,这时候可以用Headless Chrome或者HtmlUnit这类工具,模拟浏览器加载页面并执行JS,再获取完整的HTML。比如用HtmlUnit的例子:
WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_11); webClient.getOptions().setJavaScriptEnabled(true); webClient.getOptions().setCssEnabled(false); webClient.getOptions().setThrowExceptionOnScriptError(false); HtmlPage page = webClient.getPage("https://www.bing.com/search?q=vevo+USIV30300367"); String fullHtml = page.asXml(); webClient.close();
3. 遵守爬取规则
确保你的请求频率不要过高,避免触发Bing的反爬机制。可以适当添加请求间隔,不要短时间内发送大量请求,同时查看Bing的robots.txt,确认你要爬取的内容是允许的。
内容的提问来源于stack exchange,提问作者Makaveli84

