解析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小時內與您取得聯系。