一、背景
最近突然想了解一下爬虫,但是自己又不太了解python,所以学习了下Java版爬虫。在这个过程中遇到了一个问题,为了解决这个问题,百度了很多方法,两个小时候,终于找到了一个最佳方案
二、问题描述
第一个问题:想要抓取的网页是http or https请求,这个很关键,有些方法无法实现https请求。
第二个问题:关键接口相应内容为密文(除非可以解密,否则只能通过抓取网页,获取解析内容)
第三个问题:网页源码 与 下载后的文件不一致,下载后的文件为浏览器渲染后的网页
三、解决方法
3.1、http请求
若为https,则使用httpClient是无法访问通过的。该方法可以解决http请求获取页面问题
public static Page sendRequstAndGetResponse(String url) {Page page = null;// 1.生成 HttpClinet 对象并设置参数HttpClient httpClient = new HttpClient();// 设置 HTTP 连接超时 5shttpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);// 2.生成 GetMethod 对象并设置参数GetMethod getMethod = new GetMethod(url);// 设置 get 请求超时 5sgetMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);// 设置请求重试处理getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());// 3.执行 HTTP GET 请求try {int statusCode = httpClient.executeMethod(getMethod);// 判断访问的状态码if (statusCode != HttpStatus.SC_OK) {System.err.println("Method failed: " + getMethod.getStatusLine());}// 4.处理 HTTP 响应内容byte[] responseBody = getMethod.getResponseBody();// 读取为字节 数组String contentType = getMethod.getResponseHeader("Content-Type").getValue(); // 得到当前返回类型page = new Page(responseBody,url,contentType); //封装成为页面} catch (HttpException e) {// 发生致命的异常,可能是协议不对或者返回的内容有问题System.out.println("Please check your provided http address!");e.printStackTrace();} catch (IOException e) {// 发生网络异常e.printStackTrace();} finally {// 释放连接getMethod.releaseConnection();}return page;}
3.2、网页源码 与 下载后的文件不一致,下载后的文件为浏览器渲染后的网页
方法一:虽然启用了JS、CSS,并添加了延时,但获取的页面依旧不是渲染后的网页。
对于有些复杂网页并不能够实现,有些网页在获取接口参数(甚至加密),
public void test1() {// 新建一个模拟谷歌Chrome浏览器的浏览器客户端对象final WebClient webClient = new WebClient(BrowserVersion.CHROME);// 当JS执行出错的时候是否抛出异常, 这里选择不需要webClient.getOptions().setThrowExceptionOnScriptError(false);// 当HTTP的状态非200时是否抛出异常, 这里选择不需要webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);webClient.getOptions().setActiveXNative(false);// 是否启用CSS, 因为不需要展现页面, 所以不需要启用webClient.getOptions().setCssEnabled(true);// 启用JSwebClient.getOptions().setJavaScriptEnabled(true);// 很重要,设置支持AJAXwebClient.setAjaxController(new NicelyResynchronizingAjaxController());HtmlPage page;try {page = webClient.getPage("https://xxx");Thread.sleep(10000);//程的等待 因为js加载需要时间的System.out.println(page.asXml());String s = page.asXml();} catch (Exception ignored) {}finally {webClient.close();}}
方法二:直接抓取渲染后网页进行解析(耗性能,但有用)
<dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>2.33.0</version>
</dependency>
public void test3() throws InterruptedException {//驱动所在的地址System.getProperties().setProperty("webdriver.chrome.driver", "C:\\Users\\leo\\Desktop\\chromedriver.exe");ChromeOptions option = new ChromeOptions();//chrome.exe所在的地址option.setBinary("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe");ChromeDriver webDriver = new ChromeDriver(option);String str = "https://aaa#";//请求根地址webDriver.get(url);System.out.println(url);Thread.sleep(3000);//页面信息WebElement htmlElement = webDriver.findElement(By.xpath("/html"));String text = htmlElement.getText();}
四、总结
内容简单但是有效,使用爬虫技术时候,请一定要合法哦!