Jsoup简明教程

jsoup是一个操纵HTML的Java库。它提供了很多便利的API,我们可以用HTML5 DOM方法和CSS选择器来获取URL,提取和操作数据。

先看一个简单的例子,新建一个Maven项目:

在项目的pom.xml文件中添加如下依赖:

<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup --><dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.13.1</version></dependency>

确认项目下的External Libraries中包含如下jar包

我们的例子是提取到百度首页的标题,如下图所示:

使用jsoup库可以很容易做到这事儿,

package com.andy;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import java.io.IOException;public class JsoupDemo { public static void main(String[] args) throws IOException { Document document = Jsoup.connect("http://www.baidu.com").get(); System.out.println(document.title()); }}

结果如下:

通过Jsoup.connect("http://www.baidu.com").get()我们获取到了百度首页的HTML文档并返回一个Document对象(它就代表了HTML文档),使用Document对象的title()方法获取到了HTML文档的标题。

获取Document对象

有多个方法获取到Document对象。

Jsoup.parse(String html)

该方法从字符串解析出一个Document对象,

Document document = Jsoup.parse("<style>p {font-size:10px}</style>");System.out.println(document);

可以看到对于缺失的标签,jsoup库帮我们补全。

Jsoup.parseBodyFragment(String html)

该方法从字符串解析出一个Document对象,与Jsoup.parse(String html)方法不同的是,此方法会将html插入到body标签中,

Document document = Jsoup.parseBodyFragment("<style>p {font-size:10px}</style>");System.out.println(document);

Jsoup.connect(String url).get()

该方法从目标URL解析出一个Document对象,正如样例所示。

Jsoup.parse(File in, String charset, String baseUri)

该方法从文件中解析出一个Document对象,我们将百度首页的html文档保存到本地,然后用此方法得到一个Document对象:

File file = new File("./index.html");Document document = Jsoup.parse(file, "UTF-8");System.out.println(document);

提取数据

获取到了Document对象有什么用呢?我们可以通过它的很方便的方法提取数据。

DOM方法

Document对象上我们可以使用一些类DOM方法,比如:

  • getElementById(String id)
  • getElementsByTag(String tag)
  • getElementsByClass(String className)
  • getElementsByAttribute(String key)

还是用百度首页来举例:

File file = new File("./index.html");Document document = Jsoup.parse(file, "UTF-8");Elements elements = document.getElementsByTag("a");for (Element element : elements) { System.out.println(element);}

我们getElementsByTag()方法获取到了整个页面的a元素,然后打印输出每个元素。

可以用下列方法提取元素的数据:

  • attr(String key)获取元素key属性的值
  • attributes()获取元素所有属性
  • id()获取元素id属性的值
  • classNameclassNames获取元素class属性的值
  • text()获取元素内容

例如:

File file = new File("./index.html");Document document = Jsoup.parse(file, "UTF-8");Elements elements = document.getElementsByTag("a");for (Element element : elements) { System.out.println(element.text() + " : " + element.attr("href"));}

选择器方法

除了类DOM方法外,还可以使用CSS选择器语法对元素进行筛选,主要是用Element.select(String selector)方法。

File file = new File("./index.html");Document document = Jsoup.parse(file, "UTF-8");Elements elements = document.select("a[href]");for (Element element : elements) { System.out.println(element.text() + " : " + element.attr("href"));}

如上例所示,通过select()方法找到了所有带有href属性的a标签。值得注意的是,select()方法可以在DocumentElementElements对象上使用。

更多选择器语法请看Use selector-syntax to find elements

获取绝对路径

有时我们需要将资源的相对路径转换为绝对路径,我们可以用如下两种方法:

Document doc = Jsoup.connect("http://jsoup.org").get();Element link = doc.select("a").first();String relHref = link.attr("href"); // == "/"String absHref = link.attr("abs:href"); // "http://jsoup.org/"// 等价于String absLink = link.absUrl("href") // "http://jsoup.org/"

爬取豆瓣电影TOP250

了解了上述内容后,我们现在可以尝试爬取豆瓣电影TOP250啦!

观察其URLhttps://movie.douban.com/top250?start=0&filter=,可以发现页数和URL是一一对应的,start的值会等于当前页i减1乘以25,即start=(i-1)*25,因此通过改变start的值就可以请求到不同的HTML页面。我们对页面上的每部电影信息做进一步分析:

可以看到每部电影都包含在一个class名为itemdiv标签中,作为示例我们这里只提取每部电影的标题和URL。完整代码如下所示:

import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import java.io.IOException;public class JsoupDemo { public static void main(String[] args){ String baseUrl = "https://movie.douban.com/top250?start=%d&filter="; for (int i = 0; i < 10; i++) { String url = String.format(baseUrl, i * 25); try { parsePage(url); } catch (Exception e) { System.out.println("Error !!"); } } } public static void parsePage(String src) throws IOException { Document document = Jsoup.connect(src).get(); Elements elements = document.select("div.item"); for (Element element : elements) { String title = element.select("span.title").first().text(); String url = element.select("div.hd > a").first().attr("href"); System.out.println("title : " + title + " url : " + url); } }}

抓取结果如下:

相关文章