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);
        }
    }
}

抓取结果如下:

猜你喜欢

转载自www.cnblogs.com/viljw/p/12819341.html