Java实现的简单小爬虫

446 阅读2分钟

1. 背景

本文简述用Java写个简单的爬虫,通过jsoup爬取HTML,获得HTML中的数据。

2.知识

网络爬虫(又称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。

简单理解就是写一个脚本,实现从网络上爬取信息,解析信息的功能。

主要步骤:

  • 发送请求 获得 HTML 文本
  • 解析 HTML 格式的文本,从特定 HTML 标签中获得想要的数据

分解过程:

  • 1、Java 发送网络请求
  • 2、使用 jsoup类库 解析和定位到想要的内容

jsoup 是一个用于处理 HTML 的 Java 库。它使用最好的 HTML5 DOM 方法和 CSS 选择器提供了一个非常方便的 API,用于获取 URL 以及提取和操作数据。

jsoup实现了WHATWG HTML5规范,并将 HTML 解析为与现代浏览器相同的 DOM。

jsoup实现了 HTML5规范,可将 HTML 解析为与现代浏览器相同的 DOM。主要能力:

  • 从 URL、文件或字符串中抓取和解析HTML
  • 使用 DOM 遍历或 CSS 选择器查找和提取数据
  • 操作HTML 元素、属性和文本
  • 根据安全白名单清理用户提交的内容,以防止XSS攻击
  • 输出整洁的 HTML 官网地址:jsoup.org/

3. 示例

动手写一个示例,比如我想要获得 一个”基金网站“里,某个基金的信息。

1)发送请求 获得 HTML 文本 下面的代码演示了发起一个 HTTP 请求,获得 HTML 文本。

public class HttpClient {

    public static String readHtml(String urlStr) {
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        try {
            URL url = new URL(urlStr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setDoOutput(true);
            inputStream = conn.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (conn != null)
                conn.disconnect();
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

2)解析 HTML 格式的文本,从特定 HTML 标签中获得想要的数据

  • 将HTML文本丢给 Jsoup.parse(html); 获得一个 Document 文档对象。
  • 再使用 doc.select("h1.fund_name").first().text(); 搜索定位到目标位置。

“ h1.fund_name ” 的意思是,h1 标签的 class = fund_name 的元素,简单易懂。

/**
     * 获得基金最新信息
     * 表达式参考:https://www.cnblogs.com/zhangyinhua/p/8037599.html
     * 官网参考:https://jsoup.org/
     *
     * @return
     */
    public static FundInfo getInfo() {
        String urlStr = "http://finance.sina.com.cn/fund/quotes/001643/bc.shtml";
        String html = HttpClient.readHtml(urlStr);
        Document doc = Jsoup.parse(html);
        String name = doc.select("h1.fund_name").first().text();
        String funCode = doc.select("span.fund_code").first().text();
        funCode = RegularExpression.findByFirst(funCode, "\\((.*?)\\)");

        Element ele3 = doc.select("#fund_info_blk2").first();
        String worth = ele3.select("span.fund_data").get(0).text(); //单位净值
        String upAndDown = ele3.select("span.fund_data").get(1).text(); //涨跌幅
        String up_3month = ele3.select("span.fund_data").get(2).text(); //近3月涨幅
        String up_1year = ele3.select("span.fund_data").get(3).text(); //近1年涨幅
        String up_3year = ele3.select("span.fund_data").get(4).text(); //近3年涨幅
        String dataDate = doc.select("div.fund_data_date").first().text();//数据日期



        FundInfo f = new FundInfo();
        f.name = name;
        f.fundCode = funCode;
        f.worth = Float.parseFloat(worth);
        f.upAndDown = upAndDown;
        f.up_3month = up_3month;
        f.up_1year = up_1year;
        f.up_3year = up_3year;
        f.dataDate = dataDate;

        return f;
    }

4. 扩展

我的代码示例见:github.com/vir56k/java…

5. 参考:

jsoup.org/

END