java爬虫抓取动态网页(通过案例展示如何使用Jsoup进行解析案例中将获取博客园首页)
优采云 发布时间: 2021-09-19 16:11java爬虫抓取动态网页(通过案例展示如何使用Jsoup进行解析案例中将获取博客园首页)
下面是一个案例,演示如何使用jsup进行解析。在这种情况下,将获得博客花园第一页的标题和第一页上的博客文章列表
请查看代码(在前面代码的基础上操作。如果您不知道如何使用httpclient,请跳转到页面阅读):
引入依赖关系
org.jsoup
jsoup
1.12.1
实现代码。在实现代码之前,首先分析HTML结构。不用说,那么文章列表呢?按浏览器的F12键查看页面元素源代码。您会发现列表是一个大div,id=“post\u list”,而每个文章文章都是一个小div,class=“post\u item”
接下来,您可以启动代码。jsup的核心代码如下(整体源代码将在文章末尾给出):
/**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}
根据上面的代码,您会发现我通过jsup.parse(string HTML)方法解析httpclient获取的HTML内容来获取文档,然后文档可以通过两种方式获取其子元素:类似JS的getelementxxxx和类似jQuery选择器的select()。两种方法都可以。我个人建议使用select方法。对于元素中的属性,例如超链接地址,可以使用元素。Attr(string)方法获取,对于元素的文本内容,可以使用元素。要获取的Text()方法
执行代码并检查结果(我不得不感叹博客公园的朋友们真的很棒。从上面对主页HTML结构的分析到jsup分析的代码的执行,这段时间文章有这么多主页)
因为新的文章版本太快了,上面的屏幕截图与这里的输出有些不同
三、Jsoup其他用途
一、 jsup不仅可以在httpclient的工作成果中发挥作用,还可以独立工作,抓取页面,自己分析。分析能力已在上面显示。现在让我们展示如何抓取页面。事实上,这很简单。区别在于我直接获取文档,不需要通过jsup解析它。Parse()方法
除了直接访问在线资源外,我还可以解析本地资源:
代码:
public static void main(String[] args) {
try {
Document document = Jsoup.parse(new File("d://1.html"), "utf-8");
System.out.println(document);
} catch (IOException e) {
e.printStackTrace();
}
}
四、Jsoup另一个值得一提的特点
你一定有过这种经历。如果在页面文本框中输入HTML元素并在保存后查看它们,则页面布局很可能会混乱。如果你能过滤这些内容,它将是完美的
只是为了让我能做
通过jsup.clean方法使用白名单进行过滤。执行结果:
unsafe: <p>博客园
safe:
<a rel="nofollow">博客园</a></p>
五、结论
通过以上,我相信我是非常强大的。我不仅可以解析httpclient捕获的HTML元素,还可以自己抓取页面DOM。我还可以加载和解析本地保存的HTML文件
此外,我可以通过白名单过滤字符串,以筛选出一些不安全的字符
最重要的是,上述所有函数的API调用都相对简单
===============华丽的分界线=============
编写代码并不容易。就像你走之前那样~~
最后,本案例中分析博客公园主页文章列表的完整源代码附于后文:
package httpclient_learn;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
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;
public class HttpClientTest {
public static void main(String[] args) {
//1.生成httpclient,相当于该打开一个浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
//2.创建get请求,相当于在浏览器地址栏输入 网址
HttpGet request = new HttpGet("https://www.cnblogs.com/");
//设置请求头,将爬虫伪装成浏览器
request.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
// HttpHost proxy = new HttpHost("60.13.42.232", 9999);
// RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
// request.setConfig(config);
try {
//3.执行get请求,相当于在输入地址栏后敲回车键
response = httpClient.execute(request);
//4.判断响应状态为200,进行处理
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//5.获取响应内容
HttpEntity httpEntity = response.getEntity();
String html = EntityUtils.toString(httpEntity, "utf-8");
System.out.println(html);
/**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}
} else {
//如果返回状态不是200,比如404(页面不存在)等,根据情况做处理,这里略
System.out.println("返回状态不是200");
System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//6.关闭
HttpClientUtils.closeQuietly(response);
HttpClientUtils.closeQuietly(httpClient);
}
}
}
视图代码