整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          PHP 獲取網頁所有鏈接

          PHP 獲取網頁所有鏈接

          下代碼用于采集頁面時,獲取網頁中所有的鏈接,并循環輸出:

          $html=file_get_contents('http://www.runoob.com');

          $dom=new DOMDocument();

          @$dom->loadHTML($html);

          // grab all the on the page

          $xpath=new DOMXPath($dom);

          $hrefs=$xpath->evaluate("/html/body//a");

          for ($i=0; $i < $hrefs->length; $i++) {

          $href=$hrefs->item($i);

          $url=$href->getAttribute('href');

          echo $url.'<br />';

          }


          .轉換工具:PDF轉HTML

          1.本地及在線軟件:

          Abbyy FineReader/萬興PDF閱讀器支持直接導出HTML,Caliber則可轉換PDF至Zip格式再解壓

          備選:
          1.小于40M的PDF文件用Word直接導出成網頁 2.PDF閱讀器如福昕閱讀器可先轉Word后再導出網頁. 總之,如PDF閱讀器不能直轉html,可轉Word/Epub/Zip再通過解壓或者再次導出.
          可以使用在線的轉換軟件,但可能會收費或有各種限制及不穩定,我在文中有推薦了部分網址.

          2.定制開發工具包:

          • mutool 工具 : 免費開源PDF批處理工具,通過CMD命令來轉換PDF至文本/圖片/HTML網頁

          https://mupdf.com/index.htmlmupdf.com/index.html

          https://github.com/pymupdfgithub.com/pymupdf

          • poppler 命令行工具及對應的python開發包組件,也提供了命令行工具集,支持圖片單獨保存,復雜模式-C會導出一個大綱,在我體驗時出現部分格式問題,所以可以酌情參考一下再取舍.

          https://poppler.freedesktop.org/poppler.freedesktop.org/

          • pdf2htmlex工具: 基于mupdf / poppler基礎上改進,生成網頁效果好,但是DOM結構比較復雜,瀏覽器解析時較費資源,不太適合導入SM

          https://github.com/coolwanglu/pdf2htmlEXgithub.com/coolwanglu/pdf2htmlEX

          說明:pdf2htmlex生成的網頁中圖片也是base64編碼保存的,所以SM中導入后也不顯示圖片


          二. 操作流程: (使用mutool來作演示)

          1.把PDF轉換成HTML網頁 2.導入SuperMemo學習

          首選Abbyy FineReader/萬興PDF閱讀器/Mutool命令行/Word應用程序(PDF小于40M)來轉換,本文我們使用Mutool演示. 除使用Word格式(PDF小于40M直接用WORD打開,否則用福昕閱讀器先轉Word格式再用Word導出HTML).還可使用Epub或Zip格式(萬興等PDF閱讀器先轉至Epub或Caliber先轉至Zip再用解壓工具解壓. 注:Caliber貌似用的是pdf2htmlEX項目來轉換).


          1.轉換PDF至HTML

          mutool在之前文章已經作了介紹,本文不再進行安裝設置說明,你可以參考下文進行下載及配置

          一只小胖子:實踐-SuperMemo-PDF文檔圖片增量4 贊同 · 3 評論文章

          你也還可以參考官方的文檔:

          MuPDF Documentationmupdf.com/docs/index.html

          步驟一: 查看mutool 工具的轉換參數(這里用的是convert命令,其實還可以用draw命令實現)

          查看mutool的用法可一起使用的參數

          draw命令有大部分功能和convert命令是重合的,所以它的使用參數和convert命令基本一致. 如下為draw命令日常使用的中文說明,如需更具體參考你可以看我上面放置的官網文檔鏈接:

          draw命令也可實現

          MuPDF Command Line Toolswww.jianshu.com/p/a4b6a699ce17

          mutool man page - mupdf - General Commandswww.mankier.com/1/mutool#


          步驟二: 執行如下轉換命令(注意:pdf文件后是對應的PDF頁碼,如果不輸入默認轉換所有頁):

          mutool convert -F html -o myfile.html -O preserve-images Y:OneDrivePDF書籍輕松Scrum之旅.pdf 1,3,44,5-20

          cmd窗口執行命令

          如下正確生成了html文檔,瀏覽器打開如下:

          轉換帶圖片的網頁成功

          步驟三: 用IE打開網頁,Ctrl+Shift+A 導入網頁并進行學習

          網頁可直接導入SM進行學習

          上面生成的網頁中圖片默認是用base64編碼展示的,SM軟件不支持這些圖片的導入,所以增量閱讀時圖片區域會顯示出一個叉號,所以我建議在增量閱讀到這個圖片時,如果不需要這個圖片則可以直接刪除這個叉號,如果需要則可以直接從網頁或PDF源文件中復制或截圖過來,如下圖:

          SM軟件不支持base64圖片導入手動修復部分圖片的問題

          以上我是用mutool工具來實現PDF至網頁生成并學習的具體步驟,因該命令行工具現版本所支持的html導出用的是base64編碼來存儲圖片,所以如上我會增加一步手工取圖的操作(可以用簡單的腳本處理下網頁,把base64圖片文件化,然后替換圖片鏈接,具體可以參考我文末的方案).

          簡單較小的PDF文件,Word程序來導出也可以,不然則可用其它備選工具,如Abbyy FineReader或萬興PDF閱讀器(PDF轉換成HTML或轉成Epub再解壓)來實現PDF到HTML網頁的轉換,這兩個工具生成的網頁圖片是可以直接導入的,但注意,這兩個軟件也不是完美的. 比如: 軟件收費/文本識別率有時會比mutool更低 / 排版錯亂 /轉換速度慢/轉換時消耗資源高/不方便需求定制等.

          ====總結: PDF轉換至HTML網頁的方案===

          1.ABBYY FineReader / 萬興PDF閱讀器 軟件本身支持轉換文本圖形分離的網頁,只不過要收費,另外也可以直接Word程序(PDF大小限制),福昕->Word,萬興->Epub,Caliber->Zip等間接方式.

          2.在線的轉換工具,WPS在線轉換/永中在線轉換等在線轉換工具,會有各種限制及收費,不穩定等問題, 也存在一定隱私問題,無法自定規則及不方便批處理.如下放置幾個免費的在線轉換網址:

          https://www.pdf-online.com/osa/extract.aspx?o=imgwww.pdf-online.com/osa/extract.aspx?o=img

          https://www.pdftohtml.netwww.pdftohtml.net

          ConvertFiles.comConvertFiles.com


          3.mutool 命令行工具及 mupdf api 庫 / poppler / 基于前兩個軟件的pdf2htmlEX 等轉換工具

          mutool使用簡單,只不過生成網頁中圖片是用base64編碼的,上面我建議是這樣操作: 導入進SM軟件來學習時,顯示叉號但不需要的圖片可直接刪除,需要的圖片直接從網頁拷貝源圖片到SM軟件即可.如果你一定要導入圖片在SM學習可以按我文末的方法簡單處理一下生成的HTML網頁.

          poppler自帶了一套工具集,可以實現PDF轉換成文本/圖片/網頁. 使用工具pdf2html可以生成文本及圖片分離的網頁,但實驗中會有一小部分網頁格式上會有亂的情況,所以自己綜合看下效果.

          pdf2htmlEX 生成網頁效果最好,但網頁文件較大/DOM結構較復雜/網頁解析消耗資源,圖片也是返回base64,如果是要導入SM中進行增量,還是不建議了,直接用瀏覽器打開體驗還是很不錯的.


          Mutool免費開源,提供了命令行工具套件及pymupdf編程包,社區活躍,迭代的速度很快.支持多線程,網頁轉換速度相當快.方便自己定制處理,所以比較推薦.

          如下: 我們會發現mupdf官網版本修復/更新非常快,很多軟件現在沒有的功能相信很快會出現:

          代碼提交更新數據

          --------2021-01-31 增加如下--------:

          針對mutool導出html時圖片默認為base64編碼的問題.網上也有人提出過問題,官方回答是建議自己單獨寫代碼來處理一下,把base64的圖片保存至本地并用本地鏈接替換回原來的img鏈接.

          mutool-save-images-as-independent-files-manage-paragraphscomp.lang.postscript.narkive.com/N1Bes6uK/mutool-save-images-as-independent-files-manage-paragraphs

          https://github.com/pymupdf/PyMuPDF/issues/154github.com/pymupdf/PyMuPDF/issues/154

          # 方式一 : 對mutool生成的HTML網頁直接解析,解碼出圖片并替換鏈接...
          image = json.loads(pg.getText('json'))['blocks'][0]['image']  
          img = Image.open(io.BytesIO(base64.b64decode(image))) 
          #fitz.Pixmap(doc, xref)

          Collection of Recipespymupdf.readthedocs.io/en/latest/faq.html#how-to-extract-images-non-pdf-documents

          Appendix 2: Details on Text Extractiondocumentation.help/PyMuPDF/app2.html

          # 方式二: 直接使用Mupdf的API自已生成HTML,使用dict來取圖片及文本...doc = fitz.open(file_path)for page in doc:
            page.getText("dict")

          我是一只熱愛學習的小胖子,如果你也熱愛學習,并且對SuperMemo感興趣,歡迎轉發和評論!

          . 增強HttpServletResponse對象

          1. 實現一個增強的HttpServletResponse類,需要繼承javax.servlet.http.HttpServletRequestWrapper類,通過重寫自己需要增強的方法來實現(這種模式就叫做裝飾者模式),使用該增強類在加上過濾器就可以實現無編碼轉換處理代碼。

          public class MyRequest extends HttpServletRequestWrapper{
          	private HttpServletRequest req;
          	public MyRequest(HttpServletRequest request) {
          		super(request);
          		req=request;
          	}
          	@Override
          	public String getParameter(String name) {
          		//解決編碼問題,無論是post還是get請求,都不需要在業務代碼中對編碼再處理
          		String method=req.getMethod();
          		if("get".equalsIgnoreCase(method)){
          			try {
          				String str=req.getParameter(name);
          				byte[] b=str.getBytes("iso8859-1");
          				String newStr=new String(b, "utf-8");
          				return newStr;
          			} catch (UnsupportedEncodingException e) {
          				// TODO Auto-generated catch block
          				e.printStackTrace();
          			}
          		}else if("post".equalsIgnoreCase(method)){
          			try {
          				req.setCharacterEncoding("utf-8");
          			} catch (UnsupportedEncodingException e) {
          				// TODO Auto-generated catch block
          				e.printStackTrace();
          			}
          		}
          		//絕對不能刪除此行代碼,因為此行代碼返回的就是編碼之后的數據
          		return super.getParameter(name);
          	}
          }
          

          在過濾器中應用

          public class FilterTest4 implements Filter {
          	@Override
          	public void init(FilterConfig filterConfig) throws ServletException {}
          	@Override
          	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          			throws IOException, ServletException {
          		//生成增強的HttpServletRequest對象
          		HttpServletRequest req=(HttpServletRequest) request;
          		MyRequest myReq=new MyRequest(req);
          		//將增強的HttpServletRequest對象傳入過濾器執行鏈中,在后面傳入的request對象都會是增強的HttpServletRequest對象
          		chain.doFilter(myReq, response);
          		
          	}
          	@Override
          	public void destroy() {}
          }
          

          2. 文件上傳原理過程

          1. JavaWeb中實現文件上傳:

          • 客戶端:HTML頁面需要一個<form>表單,且必須設置表單的enctype屬性值為"multipart/form-data",以及method屬性值為"post"(因為get方式不支持大量數據提交);表單里有一個<input type="file" name="">的標簽,且name屬性值必須指定。
          <html>
           <head>
           <title>My JSP 'upload.jsp' starting page</title>
          	<meta http-equiv="pragma" content="no-cache">
          	<meta http-equiv="cache-control" content="no-cache">
          	<meta http-equiv="expires" content="0"> 
          	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
          	<meta http-equiv="description" content="This is my page">
           </head>
           
           <body>
           <form action="" method="post" enctype="multipart/form-data">
           <input type="text" name="name">
           	請選擇文件:<input type="file" name="upload">
           	<input type="submit" value="上傳">
           </form>
           </body>
          </html>
          
          • 服務端:主要進行IO讀寫操作。必須導入commons-fileupload和commons-io兩個jar包,可以通過請求request對象的getInputStream獲得一個流來讀取請求中的文件數據,但是如果客戶端上傳多個文件時,就會很麻煩,所以提供了commons-fileupload和commons-io兩個jar包來更方便的實現文件上傳。
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.util.List;
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import org.apache.commons.fileupload.FileItem;
          import org.apache.commons.fileupload.FileUploadException;
          import org.apache.commons.fileupload.disk.DiskFileItemFactory;
          import org.apache.commons.fileupload.servlet.ServletFileUpload;
          public class UploadServlet extends HttpServlet{
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          		/**
          		 * 1. 創建磁盤文件項工廠類 DiskFileItemFactory
          		 * 2. 創建核心解析Request類 ServletFileUpload
          		 * 3. 開始解析Request對象中的數據,并返回一個List集合
          		 * 4. List中包含表單中提交的內容
          		 * 5. 遍歷集合,獲取內容
          		 */
          		DiskFileItemFactory fac=new DiskFileItemFactory();
          		
          		ServletFileUpload upload=new ServletFileUpload(fac);
          		upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼
          		try {
          			List<FileItem> fileItems=upload.parseRequest(req);
          			for(FileItem item:fileItems){
          				//有可能是普通文本項,比如<input type="text">標簽提交上來的字符串
          				//也有可能是<input type="submit" value="上傳">上傳的文件
          				//文件項與普通項有不同的API來處理
          				//首先判斷是普通文本項還是文件項,
          				if(item.isFormField()){
          					//true表示普通文本項
          					//獲取文本項的name屬性值
          					String name=item.getFieldName();
          					//獲取對應的文本
          					String value=item.getString("utf-8");//防止中文亂碼
          					System.out.println(name+":"+value);
          				}else{
          					//false表示文件項
          					//先獲取文件名稱
          					String name=item.getName();
          					//獲取文件項的輸入流
          					InputStream in=item.getInputStream();
          					//獲取服務器端文件存儲的目標磁盤路徑
          					String path=getServletContext().getRealPath("/upload");
          					System.out.println(path);
          					//獲取輸出流,輸出到本地文件中
          					OutputStream out=new FileOutputStream(path+"/"+name);
          					//寫入數據
          					int len=0;
          					byte[] b=new byte[1024];
          					while((len=in.read(b))!=-1){
          						out.write(b,0,len);
          					}
          					in.close();
          					out.close();
          					
          				}
          			}
          		} catch (FileUploadException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          }
          

          注意:在文件上傳時,會將form表單的屬性enctype屬性值為"multipart/form-data",當提交到服務端后,無法使用 req.getParameter(name) 方法來獲取到內容,只有通過上面的方法來獲取文本項。

          2. 文件上傳相關核心類:

          • DiskFileItemFactory:相關API如下
          • public DiskFileItemFactory():無參構造器
          • public DiskFileItemFactory(int sizeThreshold, File repository):構造器,sizeThreshold設置緩沖區大小,默認10240 byte;repository表示如果過緩沖區空間小于上傳文件空間,那么會生成臨時文件,repository就是指定該臨時文件的保存路徑,如果過未上傳完成就中斷,繼續上傳時就可以通過這個臨時文件來繼續上傳。
          • public void setSizeThreshold(int sizeThreshold):設置緩沖區大小
          • public void setRepository(File repository):指定該臨時文件的保存路徑
          //改進上面的文件上傳代碼,添加一個臨時文件
          public class UploadServlet extends HttpServlet{
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          		DiskFileItemFactory fac=new DiskFileItemFactory();
          		fac.setSizeThreshold(1024*1024);//設置緩沖區為1mb
          		//設置臨時文件的本地磁盤存儲路徑
          		File repository=new File(getServletContext().getRealPath("/temp"));
          		fac.setRepository(repository);
          		ServletFileUpload upload=new ServletFileUpload(fac);
          		upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼
          		try {
          			List<FileItem> fileItems=upload.parseRequest(req);
          			for(FileItem item:fileItems){
          				if(item.isFormField()){
          					String name=item.getFieldName();
          					String value=item.getString();
          					String value=item.getString("utf-8");//防止中文亂碼
          					System.out.println(name+":"+value);
          				}else{
          					String name=item.getName();
          					InputStream in=item.getInputStream();
          					String path=getServletContext().getRealPath("/upload");
          					System.out.println(path);
          					OutputStream out=new FileOutputStream(path+"/"+name);
          					int len=0;
          					byte[] b=new byte[1024];
          					while((len=in.read(b))!=-1){
          						out.write(b,0,len);
          					}
          					in.close();
          					out.close();
          					
          				}
          			}
          		} catch (FileUploadException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          }
          
          • ServletFileUpload:相關API如下
          • public static final boolean isMultipartContent( HttpServletRequest request) :判斷表單提交上來的數據內容是否是multipart類型的數據,即 form表單的 enctype="multipart/form-data",是則返回true,否則返回false
          • public List /* FileItem */ parseRequest(HttpServletRequest request):解析request對象,返回一個泛型為FileItem 的List集合
          • public void setFileSizeMax(long fileSizeMax):設置單個文件的空間大小的最大值
          • public void setSizeMax(long sizeMax):設置所有文件空間大小之和的最大值
          • public void setHeaderEncoding(String encoding):解決上傳文件名的亂碼問題
          • public void setProgressListener(ProgressListener pListener):上傳時的進度條。
          • FileItem:封裝表單中提交的數據
          • boolean isFormField():判斷當前FileItem對象是表單中提交的文本數據項,還是文件數據項
          • String getFieldName():獲取文本項類型FileItem對象的name屬性值,即相當于表單中的 <input type="text" name="name">
          • String getString( String encoding ):獲取文本項類型FileItem對象的value值,可以指定編碼格式,也可以省略encoding不寫
          • String getName():應用于文件項類型的FileItem對象,用于獲取文件的名稱,包括后綴名
          • InputStream getInputStream():獲取輸入流
          • void delete():刪除臨時緩存文件(在輸入以及輸出流關閉后執行)

          3. 實現多文件上傳(需要js技術):主要是更改jsp頁面,通過js代碼來添加多個文件進行上傳,服務器代碼無需更改

          <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=utf-8"%>
          <%
          String path=request.getContextPath();
          String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
          %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
           <head>
           <base href="<%=basePath%>">
           <title>My JSP 'upload.jsp' starting page</title>
          	<meta http-equiv="pragma" content="no-cache">
          	<meta http-equiv="cache-control" content="no-cache">
          	<meta http-equiv="expires" content="0"> 
          	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
          	<meta http-equiv="description" content="This is my page">
           </head>
           
           <body>
           <script type="text/javascript">
           	function run(){
           		var div=document.getElementById("divId");
           		 div.innerHTML+="<div><input type='file' name='upload'><input type='button' value='刪除' onclick='del(this)'></div>"
           	}
           	function del(presentNode){
           		var div=document.getElementById("divId");
           		div.removeChild(presentNode.parentNode);
           	}
           </script>
           <div>
           	多文件上傳<br/>
           <form action="/Servlet/upload" method="post" enctype="multipart/form-data">
           	<input type="button" value="添加" onclick="run()"><br/>
           	<div id="divId">
           	
           	</div>
           	
           	<input type="submit" value="上傳">
           </form>
           </div>
           </body>
          </html>
          

          4. 關于文件上傳的一些問題:

          • 文件重名可能會產生覆蓋效果,可以在處理文件名時生成一個唯一的文件名
          • 如果所有的文件都儲存在一個文件夾中,會導致文件夾下文件過多,可以一個用戶一個文件夾,或者利用算法目錄分離等方法。

          3. 文件下載

          1. 傳統文件下載方式有超鏈接下載或者后臺程序下載兩種方式。通過超鏈接下載時,如果瀏覽器可以解析,那么就會直接打開,如果不能解析,就會彈出下載框;而后臺程序下載就必須通過兩個響應頭和一個文件的輸入流。

          2. 后臺程序下載:

          • 兩個響應頭:
          • Content-Type:其值有比如 text/html;charset=utf-8
          • Content-Disposition:其值為 attachment;filename=文件名 以附件形式打開
          • 流:需要獲取文件的輸入流,然后通過response對象的輸出流輸出到客戶端。

          主站蜘蛛池模板: 日韩免费观看一区| 麻豆精品久久久一区二区| 无码一区18禁3D| 成人丝袜激情一区二区| 国产精品一区二区三区高清在线| 精品人妻中文av一区二区三区| 中文字幕一区在线| 亚洲福利视频一区| 国模极品一区二区三区| 国产精品一区不卡| 精品无码一区二区三区亚洲桃色 | 精品一区二区三区免费观看| 99久久精品国产免看国产一区| 色狠狠色噜噜Av天堂一区| 亚洲高清毛片一区二区| 四虎一区二区成人免费影院网址| 一区二区视频在线观看| 国产丝袜一区二区三区在线观看| 国产在线精品一区免费香蕉| 亚洲一区免费视频| 国模精品一区二区三区| 免费无码A片一区二三区| 丝袜无码一区二区三区| 国内精品一区二区三区最新| 国精无码欧精品亚洲一区| 大香伊蕉日本一区二区| 久久精品黄AA片一区二区三区| 一区二区三区观看| 日韩在线观看一区二区三区| 国内国外日产一区二区| 国产乱人伦精品一区二区在线观看| 丝袜人妻一区二区三区| 国产A∨国片精品一区二区| 国产成人一区二区三区电影网站 | 国精品无码A区一区二区| 国产激情一区二区三区成人91| 色噜噜狠狠一区二区三区果冻 | 美女一区二区三区| 国产成人无码一区二区三区在线 | 无码AV一区二区三区无码 | 国产成人高清亚洲一区久久|