Java的应用领域一直给人的印象就是企业级系统开发语言,其实Java在爬虫方面也是很强的,也有很成熟的生态体系,而且强大的语言基础不论是爬取处理,数据处理都可以有足够的支撑。很早读书的时候,有看过一本爬虫的书,当时并没有坚持读完,如今工作时间不是很充足,对相关框架、技术做一些关键记录。
一、Jsoup简介
1.官网
2.功能说明
在爬虫程序中,Jsoup作为HTML解析器,爬取可以使用HttpClient等框架,Jsoup本身也支持发起常见请求,支持HTTP、HTTPS等,但对此的支持不够丰富,可应付日常场景。
Jsoup可以从文本、文件、url获取HTML页面,生成文档Document对象,并提供类似Jquery的操作方法,CSS选择器的select元素查找方式,对HTML可以进行各种灵活的解析操作。熟悉HTML及Jquery的有经验的开发人员可以非常快的上手。
二、Jsoup实操
1.操作案例
- maven依赖
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
- parse字符串获取HTML的方式
String html = "<html><body>test</body></html>";
Document document = Jsoup.parse(html);
- 通过URL发起请求获取HTML的方式(GET请求)
//网络请求一般要设置超时时间,防止程序无限制等待,这种情况在多线程很容易出现阻塞
Document document = Jsoup.connect("https://www.baidu.com")
.timeout(1000)
.get();
System.out.println(document.toString());
- 向API地址发起POST请求(POST请求)
Connection connection = Jsoup.connect("http://192.168.1.1:8080/api")
.header("Accept", "*/*")
.header("Accept-Language", "zh-CN,zh;q=0.9")
.header("Connection", "keep-alive")
.header("Content-Type", "application/x-www-form-urlencoded")
.header("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36")
.timeout(3000)
.method(Connection.Method.POST)
.ignoreContentType(true);
Map<String, String> params = new HashMap<>();
params.put("param1", "1");
params.put("param2", "2");
connection.requestBody(JSON.toJSONString(params));
connection.execute();
- HTML解析操作·方法操作(类似Jquery)
Elements elements = document.getElementsByTag("body");
其他get方法,类似Jquery,根据名字即可知道作用,如图所示:
6. HTML解析操作·CSS选择器
Element element = elements.select("p[align='center']").first();
System.out.println(element.html());
CSS选择器可参考W3School的CSS选择器参考文档:
https://www.w3school.com.cn/cssref/css_selectors.ASP
2.利用Jsoup进行文件下载(网络资源爬取)
最初爬取文件时用了很多种方案,因为文件比较大,也出了很多问题,比如利用commons-io包IoUtils进行文件下载,多线程情况下如果遇到资源问题或者网络原因很容易引起线程阻塞,因此想到需要设置超时时间,这时候就想到了Jsoup本身,但是Jsoup默认只支持1M内文件下载,超过的需要设置maxBodySize,另外,超时时间很重要,根据程序执行情况、网络情况综合考虑设置。
使用Jsoup案例如下:
Connection.Response response = Jsoup.connect(url)
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36")
.cookies(cookieMap)
.maxBodySize(30000000)
.timeout(60 * 1000)
.ignoreContentType(true)
.execute();
byte[] dataArray = response.bodyAsBytes();
获取到byteArray后就可以继续利用commons-io下的方法直接写入文件,非常方便。
另外还有一种方式,可以获取到输入缓冲流:
BufferedInputStream bufferedInputStream = response.bodyStream();