网络爬虫页面解析 (Jsoup)

Jsoup

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

1. jsoup介绍

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

jsoup的主要功能如下:

	1.从一个URL,文件或字符串中解析HTML;
	
	2.使用DOM或CSS选择器来查找、取出数据;
	
	3.可操作HTML元素、属性、文本;

先加入Jsoup依赖:

 <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.13.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.11</version>
        </dependency>

2. jsoup解析

2.1 解析url

Jsoup可以直接输入url,它会发起请求并获取数据,封装为Document对象

//1.jsoup解析url
    @Test
    public void testUrl() throws Exception{
        //解析url地址,第一个参数是访问的url,第二个参数是访问时候的超时时间
        Document doc= Jsoup.parse(new URL("http://www.itcast.cn"), 1000);
        //使用标签选择器,获取title标签中的内容
        String title = doc.getElementsByTag("title").first().text();
        //打印
        System.out.println(title);
    }

运行结果:

在这里插入图片描述
PS:虽然使用Jsoup可以替代HttpClient直接发起请求解析数据,但是往往不会这样用,因为实际的开发过程中,需要使用到多线程,连接池,代理等等方式,而jsoup对这些的支持并不是很好,所以我们一般把jsoup仅仅作为Html解析工具使用

2.2 解析字符串

先准备以下html文件

<html>
 <head> 
  <title>传智播客官网-一样的教育,不一样的品质</title> 
 </head> 
 <body>
	<div class="city">
		<h3 id="city_bj">北京中心</h3>
		<fb:img src="/2018czgw/images/slogan.jpg" class="slogan"/>
		<div class="city_in">
			<div class="city_con" style="display: none;">
				<ul>
					<li id="test" class="class_a class_b">
						<a href="http://www.itcast.cn" target="_blank">
							<span class="s_name">北京</span>
						</a>
					</li>
					<li>
						<a href="http://sh.itcast.cn" target="_blank">
							<span class="s_name">上海</span>
						</a>
					</li>
					<li>
						<a href="http://gz.itcast.cn" target="_blank">
							<span abc="123" class="s_name">广州</span>
						</a>
					</li>
					<ul>
						<li>天津</li>
					</ul>					
				</ul>
			</div>
		</div>
	</div>
 </body>
</html>

Jsoup可以直接输入字符串,并封装为Document对象

 @Test
    public void testString() throws Exception{
        //使用工具类读取文件,获取字符串
        String content = FileUtils.readFileToString(new File("C:/Users/28486/Desktop/test.html"), "utf8");
        //解析字符串
        Document document = Jsoup.parse(content);

        String title = document.getElementsByTag("title").first().text();
        System.out.println(title);
    }

在这里插入图片描述

2.3 解析文件

Jsoup可以直接解析文件,并封装为Document对象

 @Test
    public void testFile() throws Exception{
        //解析文件
        Document document = Jsoup.parse(new File("C:/Users/28486/Desktop/test.html"), "utf8");
        String title = document.getElementsByTag("title").first().text();
        System.out.println(title);
    }

在这里插入图片描述

2.4 使用dom方式遍历文档

元素获取

  • 1.根据id查询元素getElementById
  • 2.根据标签获取元素getElementsByTag
  • 3.根据class获取元素getElementsByClass
  • 4.根据属性获取元素getElementsByAttribute
    @Test
    public void testDom() throws Exception{
        //解析文件,获取Document对象
        Document document = Jsoup.parse(new File("C:/Users/28486/Desktop/test.html"), "utf8");
        //元素获取
        //1.根据id查询元素getElementById
        String cityBj = document.getElementById("city_bj").text();
        System.out.println("获取到的元素内容是: "+cityBj);
        //2.根据标签获取元素getElementsByTag
        String span = document.getElementsByTag("span").first().text();
        System.out.println(span);
        //3.根据class获取元素getElementsByClass
        String classAClassB = document.getElementsByClass("class_a class_b").first().text();
        System.out.println(classAClassB);
        String classA = document.getElementsByClass("class_a").first().text();
        System.out.println(classA);
        String classB = document.getElementsByClass("class_b").first().text();
        System.out.println(classB);
        //4.根据属性获取元素getElementsByAttribute
        String abc = document.getElementsByAttribute("abc").first().text();
        System.out.println(abc);
        //5.通过属性和属性值获取
        String href = document.getElementsByAttributeValue("href", "http://sh.itcast.cn").first().text();
        System.out.println(href);
    }

在这里插入图片描述
元素中获取数据

  • 1.从元素中获取id
  • 2.从元素中获取className
  • 3.从元素中获取属性的值attr
  • 4.从元素中获取所有属性attributes
  • 5.从元素中获取文本内容text
 @Test
    public void testData() throws Exception{
        //解析文件,获取document
        Document document = Jsoup.parse(new File("C:/Users/28486/Desktop/test.html"), "utf8");
        /*元素中获取数据
        1.从元素中获取id*/
        Element element = document.getElementById("test");
        String id = element.id();
        System.out.println("获取到的数据是:"+id);
        //2.从元素中获取className
        String className = element.className();
        System.out.println("获取到的数据是:"+className);
        Set<String> classSet = element.classNames();
        for (String str:classSet) {
            System.out.println(str);
        }
        //3.从元素中获取属性的值attr
        String id1 = element.attr("id");
        System.out.println(id1);
        //4.从元素中获取所有属性attributes
        Attributes attributes = element.attributes();
        System.out.println(attributes.toString());
        //5.从元素中获取文本内容text
        String text = element.text();
        System.out.println(text);
    }

在这里插入图片描述

2.6 Selector选择器概述

tagname: 通过标签查找元素,比如:span
#id: 通过ID查找元素,比如:# city_bj
. class: 通过class名称查找元素,比如:.class_a
[attribute]: 利用属性查找元素,比如:[abc]
[attr=value]: 利用属性值来查找元素,比如:[class=s_name]

 @Test
    public void testSelector() throws Exception{
        //解析html文件,获取document对象
        Document document = Jsoup.parse(new File("C:/Users/28486/Desktop/test.html"), "utf8");
        //tagname: 通过标签查找元素,比如:span
        Elements elements = document.select("span");
        for (Element element : elements) {
            System.out.println(element.text());
        }
        System.out.println("--------------");
        //#id: 通过ID查找元素,比如:# city_bj.
        Element element = document.select("#city_bj").first();
        System.out.println(element.text());
        System.out.println("--------------");
        // class: 通过class名称查找元素,比如:.class_a
        Element element1 = document.select(".class_a").first();
        System.out.println(element1.text());
        System.out.println("--------------");
        //[attribute]: 利用属性查找元素,比如:[abc]
        Element element2 = document.select("[abc]").first();
        System.out.println(element2.text());
        System.out.println("--------------");
        Elements elements1 = document.select("[class=s_name]");
        for (Element e : elements1) {
            System.out.println(e.text());
        }
    }

在这里插入图片描述

2.7.Selector选择器组合使用

el#id: 元素+ID,比如: h3#city_bj
el.class: 元素+class,比如: li.class_a
el[attr]: 元素+属性名,比如: span[abc]
任意组合: 比如:span[abc].s_name
ancestor child: 查找某个元素下子元素,
比如:.city_con li 查找"city_con"下的所有li
parent > child: 查找某个父元素下的直接子元素,比如:
.city_con > ul > li 查找city_con第一级(直接子元素)的ul,再找所有ul下的第一级li
parent > *: 查找某个父元素下所有直接子元素

 @Test
    public void testSelector2() throws Exception{
        //获取Document
        Document document = Jsoup.parse(new File("C:/Users/28486/Desktop/test.html"), "utf8");
        //el#id: 元素+ID,比如: h3#city_bj
        Element element = document.select("h3#city_bj").first();
        System.out.println(element.text());
        //el.class: 元素+class,比如: li.class_a
        element = document.select("li.class_a").first();
        System.out.println(element.text());
        element=document.select("span").first();
        System.out.println(element.text());
        //el[attr]: 元素+属性名,比如: span[abc]
        element=document.select("span[abc]").first();
        System.out.println(element.text());
        //任意组合: 比如:span[abc].s_name
        element=document.select("span[abc].s_name").first();
        System.out.println(element.text());
        //ancestor child: 查找某个元素下子元素,比如:.city_con li 查找"city_con"下的所有li
        Elements elements = document.select(".city_con li");
        for (Element e : elements) {
            System.out.println("遍历的结果: "+e.text());
        }
        System.out.println("----------------");
        //parent > child: 查找某个父元素下的直接子元素,
        //比如:.city_con > ul > li 查找city_con第一级(直接子元素)的ul,再找所有ul下的第一级li
        elements = document.select(".city_con > ul > li");
        for (Element e : elements) {
            System.out.println("遍历的结果: "+e.text());
        }
        System.out.println("----------------");
        //parent > * 查找某个父元素下所有直接子元素.city_con > *
        elements = document.select(".city_con > *");
        for (Element e : elements) {
            System.out.println("遍历的结果: "+e.text());
        }
    }

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值