java爬虫抓取网页数据(博客系列Java爬虫入门简介(一)——HttpClient请求 )
优采云 发布时间: 2022-03-22 20:42java爬虫抓取网页数据(博客系列Java爬虫入门简介(一)——HttpClient请求
)
博客系列
Java爬虫简介(一)——HttpClient请求(本文)
Java爬虫简介(二)——Jsoup解析HTML页面(本文)
在上一篇博客中,我们已经介绍了如何使用 HttpClient 来模拟客户端请求页面。在本篇博客中,我们将介绍如何解析获取的页面内容。
在上一节中,我们获得了页面的 HTML 源代码,但是这些源代码是提供给浏览器进行解析的。我们需要的数据其实就是页面上博客的标题、作者、简介、发布日期等。我们需要一种方法来从 HTML 源代码中解析这些信息,将其提取出来,并将其存储在文本或数据库中。在本篇博客中,我们将介绍使用 Jsoup 包来帮助我们解析页面和提取数据。
Jsoup是一个Java HTML解析器,可以直接解析一个URL地址或者解析HTML内容。它的主要功能包括解析 HTML 页面、通过 DOM 或 CSS 选择器查找和提取数据以及更改 HTML 内容。Jsoup的使用也很简单。使用Jsoup.parse(String str)方法解析我们之前获取的HTML内容得到一个Document类,剩下的工作就是从Document中选择我们需要的数据。例如,假设我们有一个收录以下内容的 HTML 页面:
第一篇博客
第二篇博客
第三篇博客
通过Jsoup,我们可以将以上三个博客的标题提取成一个List。使用方法如下:
首先,我们通过maven来介绍Jsoup
org.jsoup
jsoup
1.10.3
然后写Java来解析。
package org.hfutec.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.List;
/*******
* created by DuFei at 2017.08.25 21:00
* web crawler example
* ******/
public class DataLearnerCrawler {
public static void main(String[] args) {
List titles = new ArrayList();
List urls = new ArrayList();
//假设我们获取的HTML的字符内容如下
String html = "<a href=\"url1\">第一篇博客</a><a href=\"url2\">第二篇博客</a><a href=\"url3\">第三篇博客</a>";
//第一步,将字符内容解析成一个Document类
Document doc = Jsoup.parse(html);
//第二步,根据我们需要得到的标签,选择提取相应标签的内容
Elements elements = doc.select("div[id=blog_list]").select("div[class=blog_title]");
for( Element element : elements ){
String title = element.text();
titles.add(title);
urls.add(element.select("a").attr("href"));
}
//输出测试
for( String title : titles ){
System.out.println(title);
}
for( String url : urls ){
System.out.println(url);
}
}
}
下面简单介绍一下Jsoup的解析过程。第一步是调用parse()方法把字符对象变成Document对象,然后我们对这个对象进行操作。一般来说,提取数据就是根据标签选择数据。select() 方法的语法格式与 javascript/css 选择器的语法格式相同。一般抽取一个标签,其属性值为指定的内容。得到的结果是一个Elements的集合,也就是Elements(因为可能有很多符合条件的标签,所以结果就是一个集合)。select() 方法可以一直持续到我们想要的标签集被选中(注意我们不必从标签层级中逐层选择,我们可以直接将 select() 方法写到我们需要的标签中,例如, 这里的示例代码可以直接写成 Elements elements = doc.select("div[class=blog_title]"); 效果是一样的)。对于选定的一组元素,我们可以通过循环提取每个所需的数据。例如,如果我们需要获取标签的文本信息,可以使用 text() 方法。如果我们需要获取对应的 HTML 属性信息,可以使用 attr() 方法。我们可以看到上述方法的输出如下:
更多Jsoup解析操作请参考以下内容:
1、
2、
一个实例
让我们继续上一个爬取数据的例子来学习官方的网站博客列表来解释一个例子。我们已经知道可以使用 Jsoup 来解析爬取的 HTML 页面内容。那么我们如何查看我们需要的内容对应的标签呢?以Chrome浏览器为例,我们需要爬取这个页面的博客。首先用Chrome浏览器打开网址,然后右击博客标题,点击“Inspect”,得到HTML页面。如下所示。
图2 右击标题
图3 点击元素父元素侧边的小三角关闭代码查看
图4 确认当前博客HTML代码的一致性
经过上面的操作,我们已经可以看到所有的博客标题等信息都存放在class=card div中了。所以,我们只需要注意这个标签中的内容是如何组织的,仅此而已。如下图所示,我们需要的信息所属的标签可以通过点击小三角展开得到。
因此,解析博客列表的代码可以写成如下。
package org.hfutec.example;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
/*******
* created by DuFei at 2017.08.25 21:00
* web crawler example
* ******/
public class DataLearnerCrawler {
public static void main(String[] args) {
String url = "http://www.datalearner.com/blog_list";
String rawHTML = null;
try {
rawHTML = getHTMLContent(url);
} catch (IOException e) {
e.printStackTrace();
}
//将当前页面转换成Jsoup的Document对象
Document doc = Jsoup.parse(rawHTML);
//获取所有的博客列表集合
Elements blogList = doc.select("div[class=card]");
//针对每个博客内容进行解析,并输出
for( Element element : blogList ){
String title = element.select("h4[class=card-title]").text();
String introduction = element.select("p[class=card-text]").text();
String author = element.select("span[class=fa fa-user]").text();
System.out.println("Title:\t"+title);
System.out.println("introduction:\t"+introduction);
System.out.println("Author:\t"+author);
System.out.println("--------------------------");
}
}
//根据url地址获取对应页面的HTML内容,我们将上一节中的内容打包成了一个方法,方便调用
private static String getHTMLContent( String url ) throws IOException {
//建立一个新的请求客户端
CloseableHttpClient httpClient = HttpClients.createDefault();
//使用HttpGet方式请求网址
HttpGet httpGet = new HttpGet(url);
//获取网址的返回结果
CloseableHttpResponse response = httpClient.execute(httpGet);
//获取返回结果中的实体
HttpEntity entity = response.getEntity();
String content = EntityUtils.toString(entity);
//关闭HttpEntity流
EntityUtils.consume(entity);
return content;
}
}
最终输出如下图所示: