解析HTML文档,可以使用一些编程语言中的HTML解析库或工具。以下是一些常用的方法:
from bs4 import BeautifulSoup
# 读取HTML文档
with open('example.html', 'r') as file:
html = file.read()
# 创建BeautifulSoup对象
soup = BeautifulSoup(html, 'html.parser')
# 使用BeautifulSoup对象提取数据
# 例如,提取所有的链接
links = soup.find_all('a')
for link in links:
print(link.get('href'))
// 读取HTML文档
var html = document.documentElement.innerHTML;
// 使用DOM解析器提取数据
// 例如,提取所有的链接
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
console.log(links[i].getAttribute('href'));
}
无论你选择哪种方法,解析HTML文档的关键是了解HTML的结构和标签,并使用相应的解析器或工具来提取所需的数据。
当你解析HTML文档时,你可能会遇到以下一些常见的任务和技术:
总的来说,解析HTML文档需要一定的HTML知识和编程技巧。你需要了解HTML的结构和标签,选择合适的解析器或工具,使用选择器来定位元素,提取所需的数据,并处理特殊情况。通过不断练习和实践,你将能够更熟练地解析HTML文档并提取所需的数据。
习是一件很痛苦的事情,很多人们总问别人有没有捷径,问学习路线,好像问完了就学会了一样。其实我想说是:要是你真的想做一件事,那么就立刻去做好了,因为时间是不会等你的,在你犹豫的时候,时间早就流走了。所以与其犹豫不决不如理科开始行!
有的人说学Java要先学HTML,那就一起来看HTML是什么吧!
首先HTML 并不是一种编程语言,而是一种标记语超文本标记语言,负责展示网站的外观,用来控制各种属性的展示,要想做JavaWeb开发,HTML是必须学会的基础。
既然要学习开发,那么必须要有工具呀!
EditPlus 3
嗯!就先来认识一下HTML的一些标签
其中的主要的标签如下
<html>-------------------开始html文档
<head>--------------------开始文档头部
<title>---------------------开始文档标题
This is first page
</title>---------------------结束文档标题
</head>----------------------结束文档头部
<body>-----------------------开始文档体
Hello World.
</body>------------------------结束文档体
</html>------------------------结束html文档
新建 HTML 页面就会出现代码如下(绿色文字为注释):
一个页面的整体结构就是:
所有的内容都在<html></html>这两个标签内部。然后分为 <head> </head>头部和 <body> </body>身体两部分。
文档的头部描述了文档的各种属性和信息,包括文档的标题、在 Web 中的位置以及和其他文档的关系等。
绝大多数文档头部包含的数据都不会真正作为内容显示给读者。
<body>标签包含文档的所有内容
(比如文本、超链接、图像、表格和列表等等。)
<title> 定义文档的标题。
浏览器会以特殊的方式来使用标题,并且通常把它放置在浏览器窗口的标题栏或状态栏上。同样,当把文档加入用户的链接列表或者收藏夹或书签列表时,标题将成为该文档链接的默认名称。
下面的就算是一个简单的网页了。
让我们保存执行一下看看。
hello world!Java学习我来了!
一个成功人士的背后,必定曾经做出过勇敢而又孤独的决定。
放弃不难,但坚持很酷~
最近在项目上完成了附件上传和下载功能,是用的 fastdfs 来实现的。好记性不如烂笔头,今天把关键代码记录下来,方便以后复用。
<!--fastdfs-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-fastdfs</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2)在 application.yml 中添加 fastdfs 相关配置:
fdfsIp: http://fastdfs:8880/
fastdfs:
connecttimeout-in-seconds: 5
network-timeout-in-seconds: 10
charset: UTF-8
# token 防盗链功能
http-anti-steal-token: false
# 密钥
http-secret-key: FastDFS1234567890
# TrackerServer port
http-tracker-http-port: 8888
# 测试环境
tracker-server-list:
- fastdfs:22122
示例代码:
上述方法就是将图片的 base64 码进行转换并上传到了 fastdfs 上。以下是可复制粘贴的源码:
import org.springframework.fasfdfs.exception.FdfsException;
import org.springframework.fasfdfs.server.FastDFSClient;
@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
@Value("${fdfsIp}")
private String fdfsIp;
@Autowired
private FastDFSClient fastDFSClient;
/**
* 保存用户信息
*
* @param userDto DTO 对象
* @return success/fail
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveUser(UserDTO userDto) {
// 图片base64转换为图片url
String imgBase64 = userDto.getAvatar;
if (!StrUtil.isBlank(imgBase64)) {
String imageUri = ;
try {
imageUri = fdfsIp + fastDFSClient.uploadFileWithBase64(imgBase64, ".jpg");
} catch (FdfsException e) {
log.error("图片上传fastdfs异常", e);
}
if (StrUtil.isBlank(imageUri)) {
log.info("图片转换失败!");
return false;
}
userDto.setAvatar(imageUri);
}
// ...
}
}
关于像 word、pdf 这样的文件上传到 fastdfs,我是通过 fastdfs-client-java 这个 jar 包来实现:
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27-SNAPSHOT</version>
</dependency>
#jar中使用时需要将此文件名修改为fastdfs_client.conf 。
#也可以在jar被调用方resource下加入fastdfs_client.conf 内容如下
connect_timeout = 60
network_timeout = 120
charset = UTF-8
http.tracker_http_port = 8888
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
tracker_server =fastdfs:22122
@Data
public class FastDFSFile implements Serializable {
private static final long serialVersionUID = 2637755431406080379L;
/**
* 文件二进制
*/
private byte content;
/**
* 文件名称
*/
private String name;
/**
* 文件长度
*/
private Long size;
public FastDFSFile(byte[] content, String name, Long size){
this.content = content;
this.name = name;
this.size = size;
}
}
fastdfs 工具类相关(包含初始化 fatdfs 连接,上传、下载、删除文件):
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import java.io.IOException;
import java.io.Serializable;
/**
* @author liuyzh
* @description fastdfs上传文件,参考链接:https://blog.wuwii.com/fsds-java.html
* @date 2020-03-03
*/
@Slf4j
public class FastDFSUtils implements Serializable {
private static final long serialVersionUID = -4462272673174266738L;
private static TrackerClient trackerClient;
private static TrackerServer trackerServer;
private static StorageClient1 storageClient1;
static {
try {
//clientGloble读配置文件
ClientGlobal.init("fastdfs_client.conf");
//trackerclient
trackerClient = new TrackerClient;
trackerServer = trackerClient.getConnection;
//storageclient
storageClient1 = new StorageClient1(trackerServer, );
} catch (Exception e) {
e.printStackTrace;
}
}
/**
* fastDFS文件上传
*
* @param file 上传的文件 FastDFSFile
* @return String 返回文件的绝对路径
*/
public static String uploadFile(FastDFSFile file) {
String path = ;
try {
//文件扩展名
String ext = FilenameUtils.getExtension(file.getName);
//mata list是表文件的描述
NameValuePair mata_list = new NameValuePair[3];
mata_list[0] = new NameValuePair("fileName", file.getName);
mata_list[1] = new NameValuePair("fileExt", ext);
mata_list[2] = new NameValuePair("fileSize", String.valueOf(file.getSize));
path = storageClient1.upload_file1(file.getContent, ext, mata_list);
} catch (Exception e) {
e.printStackTrace;
}
return path;
}
/**
* fastDFS文件下载
*
* @param groupName 组名
* @param remoteFileName 文件名
* @param specFileName 真实文件名
* @return ResponseEntity<byte >
*/
public static ResponseEntity<byte> downloadFile(String groupName, String remoteFileName, String specFileName) {
byte content = ;
HttpHeaders headers = new HttpHeaders;
try {
content = storageClient1.download_file(groupName, remoteFileName);
headers.setContentDispositionFormData("attachment", new String(specFileName.getBytes("UTF-8"), "iso-8859-1"));
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
} catch (Exception e) {
e.printStackTrace;
}
return new ResponseEntity<byte>(content, headers, HttpStatus.CREATED);
}
/**
* 删除fastdfs文件
* @param storagePath 文件的全部路径 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
* @return -1失败,0成功
* @throws IOException
* @throws Exception
*/
public static Boolean deleteFile(String storagePath) {
int result = -1;
try {
result = storageClient1.delete_file1(storagePath);
} catch (IOException | MyException e) {
log.error("fastdfs删除文件异常:", e);
}
if (result == -1) {
return false;
} else {
return true;
}
}
/**
* 根据fastDFS返回的path得到文件的组名
* @param path fastDFS返回的path
* @return
*/
public static String getGroupFormFilePath(String path){
return path.split("/")[0];
}
/**
* 根据fastDFS返回的path得到文件名
* @param path fastDFS返回的path
* @return
*/
public static String getFileNameFormFilePath(String path) {
return path.substring(path.indexOf("/")+1);
}
}
@Override
@SneakyThrows
public R uploadFile(MultipartFile file) {
JSONObject jsonObject = new JSONObject;
try {
Long fileSize = file.getSize;
// 检查文件大小,不能超过5M
if (fileSize >= 5 * 1024 * 1024) {
return R.failed("附件大小不允许超过5M");
}
String attachmentName = file.getOriginalFilename;
FastDFSFile fastDFSFile = new FastDFSFile(file.getBytes, file.getOriginalFilename, file.getSize);
String attachmentPath = FastDFSUtils.uploadFile(fastDFSFile);
jsonObject.put("attachmentPath", attachmentPath);
jsonObject.put("attachmentName", attachmentName);
jsonObject.put("attachmentSize", OtherUtil.getFileSizeUnit(fileSize));
return R.ok(jsonObject);
} catch (IOException e) {
log.info("上传附件异常:", e);
}
return R.failed("附件上传异常");
}
方式一:
/**
* 案件所属附件下载
* 接口 demo:http://192.168.166.189:7700/case/download?path=group1/M00/03/CF/wKinzF5d-EOAWPuEAAGjUNtaNqM02.docx
*
* @param path fastdfs返回的路径
* @return
*/
@RequestMapping(value = "/download")
public ResponseEntity<byte> download(String path) {
// 根据附件url获取附件名称
AttachmentInfo attachmentInfo = attachmentInfoService.getAttachmentInfoByUrl(path);
// 下载后的文件名称
String specFileName = attachmentInfo.getFileName;
String filename = FastDFSUtils.getFileNameFormFilePath(path);
String group = FastDFSUtils.getGroupFormFilePath(path);
return FastDFSUtils.downloadFile(group, filename, specFileName);
}
这样就可以实现浏览器下载了。不过还可以用 nginx 的方式来完成文件的下载:
方式二:
在 nginx 的 fastdfs 相关 server 配置里面添加:
if ($arg_attname ~* .(doc|docx|txt|pdf|zip|rar|xls|xlsx|png|jpeg|jpg)$) {
add_header Content-Disposition "attachment;filename=$arg_attname";
}
如下图所示:
重启 nginx 后,这样就可以通过访问 url 来进行文件下载了。
比如:http://fastdfs:8880/group1/M00/03/CF/wKinzF5d-EOAWPuEAAGjUNtaNqM02.docx?attname=测试.docx
。
/**
* @param storagePath 文件的全部路径 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
* @return -1失败,0成功
* @throws IOException
* @throws Exception
*/
public static Boolean deleteFile(String storagePath) {
int result = -1;
try {
result = storageClient1.delete_file1(storagePath);
} catch (IOException | MyException e) {
log.error("fastdfs删除文件异常:", e);
}
if (result == -1) {
return false;
} else {
return true;
}
}
关于 fastdfs 的文件上传、下载、删除的示例代码上面都已经介绍清楚了,如果有小伙伴遇到了 fastdfs jar 包的依赖问题,也不要慌,我已经踩过坑了,出坑记录:实操:Could not autowire No beans of 'FastDFS Client' type found 的解决方法 ,可以看这篇。
好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才。
白嫖不好,创作不易。也感谢各位的支持和认可,给予我最大的创作动力吧,我们下篇文章见!
如果本篇博客有任何错误,请批评指教,不胜感激 !
☞ Ambari 2.7.3.0 安装部署 hadoop 3.1.0.0 集群视频完整版
☞ 【实战】使用 Kettle 工具将 mysql 数据增量导入到 MongoDB 中
☞ 都快2020年了,ambari自定义服务集成,你还没掌握吗?文末有福利
☞ HBase原理(一):架构理解
☞ HBase二次开发之搭建HBase调试环境,如何远程debug HBase源代码
☞ Kafka消费者 之 指定位移消费
☞ Kylin配置Spark并构建Cube(修订版)
☞ 看完您如果还不明白 Kerberos 原理,算我输!
欢迎大家留言讨论
朕已阅
*请认真填写需求信息,我们会在24小时内与您取得联系。