目录
问题:java能否实现爬虫,如何爬取
在学习爬虫的时候,我是从python入门的。爬虫的原理也不难,获取服务器返回的html文件,然后通过正则表达式对html字符串进行解析,至于想要获得什么信息,则是看自己的业务逻辑,比如获取网站上所有邮箱,所有QQ号等。而我则是想爬取网站上所有图片。
一开始学习爬虫,想要获取网站上一些元素就需要自己写正则表达式筛选了,比如获取所有链接元素,("<a>.*</a>")。但是随着学习的深入,了解到python有Beautiful Soup这个库,提供了很多方便的方法来获取网站的元素,因本人对python了解不多,浅尝辄止,就不再妄论。
此时我就想,难道java不能获取html进行解析吗,就没有实用的工具类进行调用吗?毕竟java是做网站开发的利器啊。果然,java提供了jsoup工具来做爬虫开发,而且个人觉得很好用。
jsoup简介
想要深入学习jsoup的同学可以去jsoup官网查看文档学习,使用非常简单,不难看懂。这里我先简单介绍一下。
jsoup是用于处理实际HTML的Java库。它提供了使用DOM,CSS和类似jquery的最好方法提取和处理数据的非常方便的API。
jsoup实现WHATWG HTML5规范,并将HTML解析为与现代浏览器相同的DOM。
- 从URL,文件或字符串中抓取并解析 HTML
- 使用DOM遍历或CSS选择器查找和提取数据
- 处理 HTML元素,属性和文本
- 根据安全的白名单清除用户提交的内容,以防止XSS攻击
- 输出整洁的HTML
获取jsoup
Maven
<dependency>
<!-- jsoup HTML parser library @ https://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
Gradle
// jsoup HTML parser library @ https://jsoup.org/
compile 'org.jsoup:jsoup:1.12.1'
当然你也可以通过自行下载jsoup-1.12.1.jar,并把它放入你的项目中。
jsoup几个常用的类
Document
Document是jsoup解析完html之后返回的一个对象,由Elements和TextNode组成,封装好了很多方法,可以通过它很方便地获取指定元素。获取Document对象也很简单。
- 从URL加载Document
Document doc = Jsoup.connect("http://example.com")
.data("query", "Java")
.userAgent("Mozilla")
.cookie("auth", "token")
.timeout(3000)
.post();//只需要connect()就行了,后面的方法指定http请求的一些属性,使用默认的亦可
- 从字符串加载Document
String html = "<html><head><title>First parse</title></head>"
+ "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc = Jsoup.parse(html);
- 从文件加载Document
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
该parse(File in, String charsetName, String baseUri)方法加载并解析HTML文件。如果在加载文件时发生错误,它将抛出一个IOException,您应该适当地处理它。
baseUri解析器使用该参数在找到元素之前解析文档中的相对URL 。如果您不担心此问题,可以改为传递一个空字符串。
有一种姐妹方法parse(File in, String charsetName),该方法使用文件的位置作为baseUri。如果您在本地文件系统站点上工作,并且指向该站点的相对链接也在文件系统上,则此功能很有用。
Element及Elements
获得了Document之后,我们可以通过它做一些更有趣的事情,比如获取特定元素。Element就是这些元素在java的特定实现,而Elements可以理解为Element的一个容器。获取元素方法也很简单,使用了jQuery和css的选择器,对前端熟悉的很容易理解这一点,不熟悉前端技术的也不用害怕,因为这并不难。
- 通过元素id获得Element
//获取id为content的元素
Element content = doc.getElementById("content");
- 通过元素class获得Elements
//获取class为confirmButton的所有元素
Elements confirmButtons= doc.getElementsByClass("confirmButton");
- 通过元素tag获得Elements
//获取所有链接
Elements links = doc.getElementsByTag("a");
- 还有很多,不再赘述
- getElementsByAttribute(String key)
- 元素的兄弟姐妹:siblingElements(),firstElementSibling(),lastElementSibling(),nextElementSibling(),previousElementSibling()
- parent(),children(),child(int index)
获取Element后,我们就可以使用Element封装的一些方法获取元素中的信息,比如链接<a><\a>的地址href。
Elements links = content.getElementsByTag("a");
for (Element link : links) {
String linkHref = link.attr("href");
String linkText = link.text();
}
这些是Element的常用方法:
- attr(String key)获取和attr(String key, String value)设置属性
- attributes() 获取所有属性
- id(),className()和classNames()
- text()获取并text(String value)设置文本内容
html()获取并html(String value)设置内部HTML内容 - outerHtml() 获得外部HTML值
- data()获取数据内容(例如script和style标签)
- tag() 和 tagName()
解决办法:jsoup实现爬虫功能
熟悉了jsoup之后,我们就可以很方便的实现自己的爬虫工具了。
获取目标网站的html
//这里我们没有通过jsoup的方法获取,而是使用HttpClient,效果是一样的
public String getHtml(String myURL) {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String html="";
HttpGet request = new