手把手Java爬虫教学 - 5. 项目1 - Jsoup 解析 html 页面

我们上一讲已经拿到了完整的 html 页面,这一讲我们来对我们要爬取的页面进行分析,然后去读取相应的数据

一、页面分析

打开我们要爬的页面,然后鼠标右键,选择检查

不难发现,我们要爬取的内容,都在一个 id 为 post_list 的 div 块中,也就是说,我们要先拿到这个 div。

接着再来看

每一个博客都是扔在了 article 标签中,那也就是说我们再去拿这个标签,然后里面有各种 div、a、span 标签,这些里面有我们需要的内容,解析这些内容即可。

总的来说其实还是比较容易的,现在我们来通过代码进行实现~

二、解析 html 页面

解析 html 页面,我们主要用到了一个叫 Jsoup 的解析器,同样,建议大家也去它官网上看看它的 API 接口,不是很难。除去 Jsoup 之外,还要看一个东西:XPath,这个东西也是我们要用的一个玩意,比较有趣,它的话直接去菜鸟教程、W3school 学一下就好。

1. 获取 id 为 post_list 的 div 块

...
for(int i = 1; i <= 1; i++) {
    HtmlPage page = webClient.getPage(taskUrl + i);		
	List<DomElement> blogMainDiv = page.getByXPath("//div[@id='post_list']");
}
...

这里我们直接用 page 通过 XPath 的方式进行获取。简单解释一下 //div[@id='post_list'] 这个东西

  • //:从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
  • div[@id='post_list']:获取 id 为 post_list 的 div 模块。

这里我们就可以得到一个 List 集合(因为它可能根据 XPath 解析出多条记录,所以返回的是 List 集合)。

但是!既然这里是返回的一个 List,我们还不如直接再往深拿一下。

再来观察页面,可以看到,我们要的东西其实都是在 section 中,也就是说,我们完全可以通过 XPath 拿到 section List,然后去解析 section 下面的东西,所以说我们来修改一下我们刚刚写的代码~

List<DomElement> blogMainDiv = page.getByXPath("//div[@id='post_list']/article/section");

2. 获取博客标题

上面拿到 DomElement List 之后,我们来循环它,然后通过 Jsoup 将 DomElement 转换成 Document,这样我们通过操作 Document 就可以了。

Jsoup 的 Document 有一个方法,就是通过 css 标签获取到 Element 或 Elements 结构的数据,这样我们其实就可以得到博客标题所在的 a 标签了。

List<DomElement> blogMainDiv = page.getByXPath("//div[@id='post_list']/article/section");
    for(DomElement x : blogMainDiv) {
        Document document = Jsoup.parse(x.asXml());
		
		Element section_div = document.select(".post-item-text").first();
		Element section_div_a = section_div.select("a[href]").first();
		
		String blogTitle = section_div_a.text();
        System.out.println(blogTitle);
}

这里要说一下,document.select 本身返回的是 Elements,因为我们可以观察网站结构发现,css 叫 post-item-text 的在一个 section 中只有一个,所以我这里直接用 first 方法获取到第一个即可。下面 section_div.select("a[href]") 也是同理。

然后我们来测试一下。

可以看到,是没有问题的。

3. 获取博客连接

博客连接是存储在 a 标签的 href 属性中,我们可以通过 Element 的 attr 方法进行获取。

String blogUrl = section_div_a.attr("href");

通过测试我们也可以看到,是没有问题的。

4. 获取到所有我们需要的信息

这里我们根据以上的这两种方式,拿到所有我们需要的信息,这里我直接上代码了~

List<DomElement> blogMainDiv = page.getByXPath("//div[@id='post_list']/article/section");
for(DomElement x : blogMainDiv) {
	Document document = Jsoup.parse(x.asXml());
	
	Element section_div = document.select(".post-item-text").first();
	Element section_div_a = section_div.select("a[href]").first();
	
	String blogTitle = section_div_a.text();
	String blogUrl = section_div_a.attr("href");
	
	Element section_div_p = section_div.select("p").first();
	String content = section_div_p.text();
	Element section_div_p_a = section_div_p.select("a[href]").first();
	// cnblog 博客页可能存在没有头像的博客。
	String authorUrl = null;
	String imageUrl = null;
	if(section_div_p_a != null) {
		authorUrl = section_div_p_a.attr("href");
		Element section_div_p_a_img = section_div_p_a.select("img[src]").first();
		imageUrl = section_div_p_a_img.attr("src");
	}
	
	Element section_footer = document.select(".post-item-foot").first();
	Element section_footer_a_span = section_footer.select("a span").first();
	String authorName = section_footer_a_span.text();
	
	Element section_footer_span_span = section_footer.select("span span").first();
	String blogCreateDt = section_footer_span_span.text();
}

这里同样要有补充说明

  • 大家可以多翻几页博客,你会发现一个问题,有的博客是没有用户头像的,也就是说我们获取不到这个,所有才要有判空处理
  • 因为页面上没有单独的用户 id,所以我们到时候要通过解析用户的主页地址来获取,所以不要着急。
  • 这里其实有一个 bug,如果没有用户头像,我这里其实连用户的 url 也没有获取到,但其实我们可以在下面获取用户名称的时候去拿,但是我懒得写了,你要是为了完美可以自己修改一下~

到这里为止,我们的页面就解析完成了,下一讲我们来说保存数据(保存数据时也有坑~)


这一讲就讲到这里,有问题可以联系我:QQ 2100363119,欢迎大家访问我的个人网站:https://www.lemon1234.com

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Java Jsoup是一个用于解析HTML文档的开源库。通过使用Jsoup,您可以轻松地从HTML文档中提取数据或进行数据操作。以下是使用Java Jsoup解析HTML的基本步骤: 1. 下载Jsoup库:您可以从Jsoup的官方网站(https://jsoup.org/)下载Jsoup库的最新版本。 2. 导入Jsoup库:将下载的Jsoup库的JAR文件导入到您的Java项目中。 3. 创建连接:使用Jsoup.connect()方法创建一个Connection对象,将HTML文档的URL作为参数传递给该方法。 4. 获取Document对象:使用Connection对象的get()方法获取一个Document对象,该对象表示整个HTML文档。 5. 使用选择器进行数据提取:使用Jsoup的选择器语法,您可以根据HTML元素的标签、类名、ID等属性来选择和提取数据。 以下是一个基本的Java Jsoup解析HTML的示例代码: ```java import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class HtmlParser { public static void main(String[] args) { try { // 创建连接 Connection connection = Jsoup.connect("http://example.com"); // 获取Document对象 Document document = connection.get(); // 使用选择器提取数据 Elements links = document.select("a[href]"); for (Element link : links) { System.out.println("Link: " + link.attr("href")); System.out.println("Text: " + link.text()); } } catch (IOException e) { e.printStackTrace(); } } } ``` 这个示例代码将从"http://example.com"网页中提取所有链接的URL和文本,并打印出来。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

他 他 = new 他()

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值