Jsoup爬虫

1 Jsoup简介

        Jsoup是一个Java库,它简化了使用真实世界的HTML和XML。它提供了一个易于使用的API,用于使用DOM API方法、CSS和xpath选择器进行URL获取、数据解析、提取和操作。

        Jsoup实现了WHATWG HTML5规范,并将HTML解析为与现代浏览器相同的DOM。

  • 从URL、文件或字符串中抓取和解析HTML 
  • 使用DOM遍历或CSS选择器查找和提取数据 
  • 操作HTML元素、属性和文本 
  • 根据安全列表清除用户提交的内容,以防止XSS攻击 
  • 输出整洁的HTML

        Jsoup设计用于处理各种各样的HTML;从原始和验证,到无效标签汤;jsoup将创建一个合理的解析树。

2 爬取一个页面

        创建Maven项目,并添加Jsoup依赖,内容如下。

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.13.1</version>
</dependency>

        我们先来爬取单个页面(王者荣耀官方网站-腾讯游戏),了解Jsoup的基本使用。

        获取页面内容

Document doc = null;
try {
	doc = Jsoup.connect("https://pvp.qq.com/index.shtml").get();
} catch (IOException e) {
	e.printStackTrace();
}
String content = doc.html();

        保存页面到本地

File file = new File("d:/pvp.qq.com");
if (!file.exists()) {
	file.mkdirs();
}
try {
	FileWriter writer = new FileWriter(file.getPath() + "/index.html");
	writer.write(content);
	writer.flush();
	writer.close();
} catch (IOException e) {
	e.printStackTrace();
}

        完整代码

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

public class PageFetch {

	public static void main(String[] args) {
		fetchPage();
	}
	/**
	 * 爬取页面并保存
	 */
	public static void fetchPage() {
		Document doc = null;
		try {
			doc = Jsoup.connect("https://pvp.qq.com/index.shtml").get();
		} catch (IOException e) {
			e.printStackTrace();
		}
		String content = doc.html();
		File file = new File("d:/pvp.qq.com");
		if (!file.exists()) {
			file.mkdirs();
		}
		try {
			FileWriter writer = new FileWriter(file.getPath() + "/index.html");
			writer.write(content);
			writer.flush();
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

3 保存图片

        在保存的首页中找到背景图的网址

//436行
background-image:url(//ossweb-img.qq.com/upload/webplat/info/yxzj/20200807/9771361431874.jpg)

        打开图片链接

URL url = new URL("https://ossweb-img.qq.com/upload/webplat/info/yxzj/20200807/9771361431874.jpg");
URLConnection conn = url.openConnection();
conn.setConnectTimeout(8 * 1000);

        获取图片对应的输入流

InputStream in = conn.getInputStream();

        保存图片到本地

byte[] buff = new byte[1024];
int len = 0;
File file = new File("d:/pvp.qq.com");
if (!file.exists()) {
	file.mkdirs();
}
FileOutputStream out = new FileOutputStream(file.getPath() + "/9771361431874.jpg");

while ((len = in.read(buff)) != -1) {
    out.write(buff, 0, len);
}
out.close();
in.close();

        完整代码

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

public class ImageSave {

	public static void main(String[] args) {
		saveImage();
		parsePage();
		editPage();
	}
	/**
	 * 保存图片
	 */
	public static void saveImage() {
        try {
        	//首页背景图<div class="kv-bg-container"><div class="kv-bg" style="background-image:url(...
			URL url = new URL("https://ossweb-img.qq.com/upload/webplat/info/yxzj/20200807/9771361431874.jpg");
			URLConnection conn = url.openConnection();
	        conn.setConnectTimeout(8 * 1000);
	        InputStream in = conn.getInputStream();
	        byte[] buff = new byte[1024];
	        int len = 0;
	        File file = new File("d:/pvp.qq.com");
			if (!file.exists()) {
				file.mkdirs();
			}
	        FileOutputStream out = new FileOutputStream(file.getPath() + "/9771361431874.jpg");

	        while ((len = in.read(buff)) != -1) {
	            out.write(buff, 0, len);
	        }
	        out.close();
	        in.close();
		}  catch (IOException e) {
			e.printStackTrace();
		}
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/577608.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从零开始利用MATLAB进行FPGA设计(五)详解双口RAM

创作于谱仪算法设计过程中的数字能谱生成模块设计。 往期回顾&#xff1a; 从零开始利用MATLAB进行FPGA设计&#xff08;四&#xff09;生成优化HDL代码 从零开始利用MATLAB进行FPGA设计&#xff08;三&#xff09;将Simulink模型转化为定点数据类型 目录 1.关于双口RAM …

大模型咨询培训老师叶梓:利用知识图谱和Llama-Index增强大模型应用

大模型&#xff08;LLMs&#xff09;在自然语言处理领域取得了显著成就&#xff0c;但它们有时会产生不准确或不一致的信息&#xff0c;这种现象被称为“幻觉”。为了提高LLMs的准确性和可靠性&#xff0c;可以借助外部知识源&#xff0c;如知识图谱。那么我们如何通过Llama-In…

Web前端开发之CSS_1

CSS选择器字体属性背景属性文本属性表格属性 1. CSS 1.1 CSS简介 CSS&#xff08;Cascading Style Sheets&#xff09;层叠样式表&#xff0c;又叫级联样式表&#xff0c;简称样式表。CSS文件后缀名为 .css 。CSS用于HTML文档中元素样式的定义。使用CSS可以让网页具有美观一致…

算法 || 二分查找

目录 二分查找 在排序数组中查找元素的第一个和最后一个位置 搜索插入位置 一个数组经过划分后具有二段性的都可以用二分查找 二分查找 704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; ​ 暴力解法&#xff1a;直接遍历数组&#xff0c;找到 target 便返回下标&am…

【blog项目】layui与jquery冲突导致鼠标悬停事件失效、如何调用layui.use()作用域里的方法

blog项目前台展示——查询数据库中的文章类型并展示时出现的bug 1 正常演示 2 用jquery查询数据库并添加到页面后 3 相关代码 <script src"/static/jquery-2.1.4.js"></script> <script src"/static/layui/layui.js"></script> …

排序算法-计数排序

一、计数排序 这种排序算法 是利用数组下标来确定元素的正确位置的。 如果数组中有20个随机整数&#xff0c;取值范围为0~10&#xff0c;要求用最快的速度把这20个整数从小到大进行排序。 很大的情况下&#xff0c;它的性能甚至快过那些时间复杂度为O(nlogn&#xff09;的排序。…

使用PyCharm开发工具创建工程

一. 简介 前面文章实现了开发 python程序使用的 开发工具PyCharm&#xff0c;本文来学习使用 PyCharm开发工具创建一个 python工程。 二. 使用PyCharm开发工具创建工程 1. 首先&#xff0c;打开 PyCharm开发工具&#xff0c;打开 "New project" 选项&#xff1a; …

git如何查询回退之前的提交记录

git如何查询回退之前的提交记录 使用 git reflog 命令&#xff1a; 使用 git reflog 命令&#xff1a; git refloggit reflog 显示的是你的本地引用日志&#xff0c;它包含了所有HEAD指向变更的历史记录&#xff0c;即使那些已经被删除的提交也会出现在这里。当你误操作回退并…

一款可视化正则表达式工具

regex-vis是一款在线免费且可视化的正则表达式工具 界面图&#xff1a; 只能输入由26个英文字母组成的字符串 ^[A-Za-z]$ 只能输入数字 ^[0-9]*$测试错误 测试正确 快来感受一下叭 官方网址&#xff1a; Regex VisRegex visualizer & editor, make the regular expr…

Java根据模板动态生成Pdf(添加页码、文件加密、Spire免费版本10页之后无法显示问题、嵌入图片添加公章、转Base64)

Java根据模板动态生成Pdf&#xff1a;添加页码、文件加密、Spire免费版本10页之后无法显示问题、嵌入图片添加公章、转Base64 引言【Java根据模板动态生成Pdf资源地址】示例一&#xff1a;动态生成带页码的PDF报告示例二&#xff1a;加密PDF以保护敏感信息示例三&#xff1a;应…

设计模式——终止模式之两阶段终止模式

文章目录 1. 错误思路2. 两阶段终止模式2.1 利用 isInterrupted2.2 利用停止标记interrupt-打断park Two Phase Termination 在一个线程 T1 中如何“优雅”终止线程 T2&#xff1f;这里的【优雅】指的是给 T2 一个料理后事的机会。 1. 错误思路 使用线程对象的 stop() 方法停…

容器工作流

背景 目前某平台使用计算容器和解析容器&#xff0c;这两种容器目前通过rabbitmq消息来进行链接&#xff0c;形成容器工作流&#xff0c;使用容器工作流框架可以省去两个容器中间环节的控制&#xff0c;不需要再使用java代码对容器的操作&#xff0c;通过容器工作流框架即可控…

Docker常见问题排查思路与实战

Docker作为一种流行的容器化技术&#xff0c;已经在众多场景中得到广泛应用。然而&#xff0c;在使用过程中&#xff0c;我们难免会遇到各种问题。本文将介绍一些常见的Docker问题及其排查思路&#xff0c;并通过实战案例帮助大家更好地理解和应对这些挑战。 1. Docker容器启动…

OpenHarmony语言基础类库【@ohos.util.LinkedList (线性容器LinkedList)】

LinkedList底层通过双向链表实现&#xff0c;双向链表的每个节点都包含对前一个元素和后一个元素的引用。当需要查询元素时&#xff0c;可以从头遍历&#xff0c;也可以从尾部遍历&#xff0c;插入、删除效率高&#xff0c;查询效率低。LinkedList允许元素为null。 LinkedList…

数据库和表创建练习

一丶要求 1.创建一个数据库db_classes 2 创建一行表db_hero 3. 将四大名著中的常见人物插入这个英雄表 二丶创建db_classes一个数据库, 使用数据库默认的字符集 create database db_classes; 三丶创建一行表db_hero 1.先切换到我们创建的db_classes;数据库中 use db_class…

RabbitMQ中的交换机类型

交换机类型 可以看到&#xff0c;在订阅模型中&#xff0c;多了一个exchange角色&#xff0c;而且过程略有变化&#xff1a; Publisher&#xff1a;生产者&#xff0c;不再发送消息到队列中&#xff0c;而是发给交换机 Exchange&#xff1a;交换机&#xff0c;一方面&#xff…

03 后端入参校验:自定义注解实现

03 后端入参校验&#xff1a;自定义注解实现 一、前言二、实现1、新建Spring Boot项目2、引入依赖3、新建注解类4、新建校验器5、全局异常处理器6、编写Controller7、新建实体类8、启动并测试 一、前言 在 Java 后端开发中&#xff0c;为了实现入参校验&#xff0c;常常会使用…

【SpringCloud】CircuitBreaker断路器之Resilience4J快速入门

【SpringCloud】CircuitBreaker断路器之Resilience4J快速入门 文章目录 【SpringCloud】CircuitBreaker断路器之Resilience4J快速入门1. 概述2. 服务熔断服务降级(CircuitBreaker)2.1 案例说明2.1.1 基于计数的滑动窗口2.1.2 测试2.2.1 基于时间的滑动窗口2.2.2 测试 3. 隔离(B…

多行Textview 计算切分后的长度,并回退长度

实现类似的效果&#xff0c;一个多行的 textview&#xff0c; 如果赋值一个超长的字符&#xff0c;尾部长度回退部分&#xff0c;并添加 ... 最后添加一个详情按钮。 如果不超长则不显示详情 效果如图&#xff1a; 获取截断之后的字符长度 fun getLimitedCharacterCount(textV…

更新!!!Unity移动端游戏性能优化简谱

UWA官方出品&#xff0c;结合多年优化经验撰写了《Unity移动端游戏性能优化简谱》&#xff0c;文章从Unity移动端游戏优化的一些基础讨论出发&#xff0c;例举和分析了近几年基于Unity开发的移动端游戏项目中最为常见的部分性能问题&#xff0c;并展示了如何使用UWA的性能检测工…