网络爬虫(二)

四叶草 2020-02-15

    在我们抓取到页面之后,还需要对页面进行解析。整个页面都是字符串的形式,可以使用字符串处理工具来解析页面,也可以使用正则表达式,但这些方法都会带来很大的开发成本。所以我们需要一款准们解析 html 页面的工具。

Jsoup

    jsoup是一款 java 的 HTML 解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

    主要功能:

        1. 从URL,文件或字符串中解析HTML;

        2. 使用DOM 或 CSS选择器来查找、取出数据;

        3. 可操作 HTML元素、属性、文本(基本不使用)

使用:

    1. 导入依赖坐标(jsoup、commons-io、commons-lang3)

    2.1. 测试代码,解析URL

@Test    
    public void urlFun() throws Exception {
        // 解析URL地址,参数:访问的url,访问时的超时时间
        Document doc = Jsoup.parse(new URL("http://112.124.1.187/"),10000);
    
        // 使用标签选择器
        String title = doc.getElementsByTag("title").first().text();
    
        System.out.println(title);
    }

    ps: 这里我们可以得出,Jsoup 可以代替 HttpClient 直接发起请求数据。但是我们往往不会这么做,因为实际开发中,需要使用到多线程、连接池、代理等等,而 Jsoup 对这些的支持并不是很好,所以我们一般把 Jsoup 仅仅作为 html 解析工具使用。

     2.2. 测试代码,解析字符串

@Test
    public void strFun() throws Exception {
        // 从文件获取字符串
        String content = FileUtils.readFileToString(new File("C:\\Users\\24360\\Desktop\\a.html"),"utf-8");
    
        // 解析字符串
        Document doc = Jsoup.parse(content);
    
        // 使用标签选择器
        String title = doc.getElementsByTag("title").first().text();
    
        System.out.println(title);
    }

     2.3. 测试代码,解析文件

@Test
    public void strFun() throws Exception {
    
        // 解析文件
        Document doc = Jsoup.parse(new File("C:\\Users\\24360\\Desktop\\a.html"),"gbk");
    
        // 使用标签选择器
        String title = doc.getElementsByTag("title").first().text();
    
        System.out.println(title);
    } 

     3. 使用dom解析

@Test
    public void domTest() throws IOException {
        // 解析文件,获取Document对象
        Document doc = Jsoup.parse(new File("C:\\Users\\24360\\Desktop\\a.html"),"gbk");

        // 1.根据id获取元素: getElementById
        Element element1 = doc.getElementById("header");
//        System.out.println(element1.text());

        // 2.根据标签获取元素: getElementsByTag
        Element element2 = doc.getElementsByTag("span").get(2);
        System.out.println(element2.text());

        // 3.根据class获取元素: getElementsByClass
        Element element3 = doc.getElementsByTag("class_a").get(0);
        System.out.println(element3.text());
        // 4.根据属性获取元素: getElementsByAttribute
        Element element4 = doc.getElementsByTag("href").get(0);
        System.out.println(element4.text());
        // 4.2 如果有多个属性名相同的情况,也可以根据属性-值 来获取
        Element element5 = doc.getElementsByAttributeValue("href","http://www.baidu.com").get(0);
        System.out.println(element5.text());
    }

     4. 从元素中获取数据

    如:<a id="baidu" class="class_a class_b" href="http://www.baidu.com">百度</a>

@Test
    public void attrTest() throws IOException {
        // 解析文件,获取Document对象
        Document doc = Jsoup.parse(new File("C:\\Users\\24360\\Desktop\\a.html"),"gbk");
        // 1.根据id获取元素: getElementById
        Element ele = doc.getElementById("baidu");
    
        // 元素中获取数据
        // 1.元素中获取id
        String strId = ele.id();
        System.out.println(strId);  // baidu
    
        // 2.元素中获取类名
        String className = ele.className();
        System.out.println("所有类名:" + className);    // 所有类名:class_a class_b
        Set<String> classSet = ele.classNames();
        for(String s : classSet){            // class_a class_b
            System.out.println(s); 
        }
        // 3.元素中获取对应属性的值
        String attr = ele.attr("href"); //http://www.baidu.com
        System.out.println(attr);
    
        // 4 获取所有属性
        Attributes attrs = ele.attributes();
        System.out.println(attrs.toString());   // id="baidu" class="class_a class_b" href="http://www.baidu.com"
    }

    5.1 使用 Selector 选择器

       tagname:通过标签查找元素,例:span

        #id:通过id查找元素,例:#group

        .class:通过类名查找元素,例:.class_a

        [attribute]:通过属性查找元素,例:[abc]

        [attr=value]:通过属性值查找元素,例:[class=sn]

    如:

<a id="baidu" class="class_a class_b" href="http://www.baidu.com">百度</a>

<div abc="123">属性值</div>

@Test    
    public void selectorTest() throws IOException {
        // 解析文件,获取Document对象
        Document doc = Jsoup.parse(new File("C:\\Users\\24360\\Desktop\\a.html"),"gbk");
    
        //  tagname:通过标签查找元素,例:span
        Element e1 = doc.select("a").get(0);
        System.out.println(e1.text());              // 百度
        //  #id:通过id查找元素,例:#baidu
        Element e2 = doc.select("#baidu").get(0);
        System.out.println(e2.text());              // 百度
        //  .class:通过类名查找元素,例:.class_a
        Element e3 = doc.select(".class_a").get(0);
        System.out.println(e3.text());              // 百度
        //  [attribute]:通过属性查找元素,例:[abc]
        Element e4 = doc.select("[abc]").get(0);
        System.out.println(e4.text());              // 属性值
        //   [attr=value]:通过属性值查找元素,例:[abc=123]
        Element e5 = doc.select("[abc=123]").get(0);
        System.out.println(e5.text());              // 属性值
    }

    5.2 Selector 选择器组合使用

        el#id:元素+ID,例:h3#group

        el.class:元素+类名,例:h3.class_a

        el[attr]:元素+属性名,例:span[abc]

        任意组合:例:span[abc].class_a

        ancestor child:查找某个元素下子元素,例:.class_a li,查找“.class_a”下的所有li

        parent > child:查找某个父元素下的直接子元素(第一级)

        parent > *:查找某个父元素下的所有直接子元素

相关推荐