Jsonp爬虫

本文最后更新于:1 个月前

Jsoup和HtmlUnit简单实战

本技术需要一定的前端基础和JAVA网络编程相关知识,如还不了解自行百度补充

一、Jsoup简介

jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

网页获取和解析速度飞快,推荐使用。
主要功能如下:

  1. 从一个URL,文件或字符串中解析HTML;
  2. 使用DOM或CSS选择器来查找、取出数据;
  3. 可操作HTML元素、属性、文本;

注意:Jsoup只能解析网页,不能爬电影和音乐

二、Jsoup入门实战讲解

首先创建一个java的maven项目作为本次讲解的例子

导入maven依赖如下

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
</dependency>

首先我们要爬取京东的英语六级资料信息,我们在搜索框中输入”cet6”,地址栏如图所示

image-20200615225858019

现在我们得到了我们要获取的请求地址

https://search.jd.com/Search?keyword=cet6

可以看出,返回的是浏览器的Document对象,在js中可以使用的代码这里都能用

image-20200615230420474

接下来通过审查元素找到商品列表的div,并拿到div下的li标签

image-20200615230734537

接下来我们按照此方法,拿到相应的标签,并运行,运行结果如下,代码在下方给出

image-20200615232057442

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class HtmlParseUtils {
public static void main(String[] args) throws IOException {
//请求地址 https://search.jd.com/Search?keyword=cet6
String url = "https://search.jd.com/Search?keyword=cet6";
//解析网页 (返回的是浏览器的Document对象,在js中可以使用的代码这里都能用)
Document document = Jsoup.parse(new URL(url), 10000);
Element element = document.getElementById("J_goodsList");
//获取所有li冤死
Elements elements = element.getElementsByTag("li");
for (Element el : elements) {
//拿到商品的图片(注意:如果图片未能找到,可能是因为网站使用了懒加载的方式)
String img = el.getElementsByTag("img").eq(0).attr("src");

//String img = el.getElementsByTag("img").eq(0).attr("source-data-lazy-img");如果上面的方法未能拿到,使用这个

String price = el.getElementsByClass("p-price").eq(0).text();//拿到商品的价格

String name = el.getElementsByClass("p-name").eq(0).text();//商品名字

System.out.println("===================================================");
System.out.println(img);
System.out.println(price);
System.out.println(name);
}
}
}

讲解到这里相信大家已经对Jsoup有了基本的了解,需要工具类的话把他封装一下即可,下面来说说怎么爬取Ajax

三、HtmlUnit简介

比较推荐使用HtmlUnit来进行网页抓取主要是因为:

  • 对于使用java实现的网页爬虫程序,我们一般可以使用apache的HttpClient组件进行HTML页面信息的获取,HttpClient实现的http请求返回的响应一般是纯文本的document页面,即最原始的html页面。
  • 对于一个静态的html页面来说,使用httpClient足够将我们所需要的信息爬取出来了。但是对于现在越来越多的动态网页来说,更多的数据是通过异步JS代码获取并渲染到的,最开始的html页面是不包含这部分数据的。

htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容。项目可以模拟浏览器运行,被誉为java浏览器的开源实现。这个没有界面的浏览器,运行速度也是非常迅速的。采用的是Rhinojs引擎。模拟js运行。

说白了就是一个浏览器,这个浏览器是用Java写的无界面的浏览器,正因为其没有界面,因此执行的速度还是可以滴,HtmlUnit提供了一系列的API,这些API可以干的功能比较多,如表单的填充,表单的提交,模仿点击链接,由于内置了Rhinojs引擎,因此可以执行Javascript。
网页获取和解析速度较快,性能较好,推荐用于需要解析网页脚本的应用场景。

1
2
3
4
5
6
7
<!-- https://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit -->
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.41.0</version>
</dependency>

四、HtmlUnit+Jsoup请求Ajax内容

现在实战一下,我们请求的网站就是本博客,请求地址为

1
https://www.yxlyz.net/index.php/search/设计模式

页面如下

image-20200618104442033

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package net.yxlyz.utils;

import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;

/**
* @Author Saraph1nes
* @Date 2020/6/15 23:36
* @Version 1.0
*/
public class HtmlUnitDemo {
public static void main(String[] args) throws IOException {
final WebClient webClient = new WebClient(BrowserVersion.CHROME);//新建一个模拟谷歌Chrome浏览器的浏览器客户端对象

webClient.getOptions().setThrowExceptionOnScriptError(false);//当JS执行出错的时候是否抛出异常, 这里选择不需要
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//当HTTP的状态非200时是否抛出异常, 这里选择不需要
webClient.getOptions().setActiveXNative(false);
webClient.getOptions().setCssEnabled(false);//是否启用CSS, 因为不需要展现页面, 所以不需要启用
webClient.getOptions().setJavaScriptEnabled(true); //很重要,启用JS
webClient.setAjaxController(new NicelyResynchronizingAjaxController());//很重要,设置支持AJAX

HtmlPage page = null;
try {
page = webClient.getPage("https://www.yxlyz.net/index.php/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F");//尝试加载上面图片例子给出的网页
} catch (Exception e) {
e.printStackTrace();
}finally {
webClient.close();
}

webClient.waitForBackgroundJavaScript(10000);//异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束

String pageXml = page.asXml();//直接将加载完成的页面转换成xml格式的字符串

//下面的代码就是对字符串的操作了,常规的爬虫操作,用到了比较好用的Jsoup库

Document document = Jsoup.parse(pageXml);//获取html文档
List<Element> infoListEle = document.getElementById("tab_1").getElementsByAttributeValue("class", "list-group-item");//获取元素节点等
for (Element element : infoListEle) {
System.out.println(element.getElementsByTag("a").text());
System.out.println(element.getElementsByTag("a").attr("href"));
}
}
}

结果为:


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!