循环爬取图片_Java爬取简单的网页内容和图片
Java爬取簡單的網頁內容和圖片
根據java網絡編程相關的內容,使用jdk提供的相關類可以得到url對應網頁的html頁面代碼。
針對得到的html代碼,通過使用正則表達式即可得到我們想要的內容。
比如,我們如果想得到一個網頁上所有包括“java”關鍵字的文本內容,就可以逐行對網頁代碼進行正則表達式的匹配。最后達到去除html標簽和不相關的內容,只得到包括“java”這個關鍵字的內容的效果。
從網頁上爬取圖片的流程和爬取內容的流程基本相同,但是爬取圖片的步驟會多一步。
需要先用img標簽的正則表達式匹配獲取到img標簽,再用src屬性的正則表達式獲取這個img標簽中的src屬性的圖片url,然后再通過緩沖輸入流對象讀取到這個圖片url的圖片信息,配合文件輸出流將讀到的圖片信息寫入到本地即可。
爬蟲除這兩種玩法外,還有著許多的應用,比如還可以爬取一個網頁上所有的郵箱、電話號碼等等。
運行效果:
這些內容是我從csdn首頁中根據“你”這一個關鍵字得到的。
這些是我從一些網站得到的圖片
問題:
在看似沒有問題的爬取代碼背后其實還是存在著許多問題的,該程序只是對爬蟲最初級的應用。比如我發現部分內容的html在瀏覽器的“檢查”功能中明明存在,但是在網頁源代碼中就沒有了相關的內容。還有文本匹配的正則表達式部分也存在問題。
在img src屬性中,有部分圖片的url是不帶協議的(如:https://),還有部分圖片的url是不帶圖片后綴(jpg、png、gif...)的。前者導致程序無法解析這個url,后者導致無法給下載的圖片統一采用原命名。
有時匹配到的img src值還會出現非圖片url的情況。還有時從頁面上獲取到的內容是unicode編碼值。以及部分網站做了反爬蟲處理等...
以上問題因為我對java知識、web知識、網絡知識還有正則的知識了解的很少,所以我目前都無法解決。
這些問題就導致最后真正從網頁上爬下來的內容,只是原網頁很少的一部分。
我相信在以后這些問題都是會被逐個解決的。
另外我在程序中使用了多線程的功能,以達到可以在多個網頁“同時”爬取的效果。
下面給出該程序的源代碼。
編譯環境:
windows jdk 9 idea
代碼:
//Main.java 主類
package pers.baijiaming.download.main;//主類
public class Main
{public static void main(String[] args){createImageDownloadThread ("https://www.bilibili.com/", "downloadImg/b站/");createImageDownloadThread("https://cn.bing.com/images/search?q=%E7%A6%8F%E5%88%A9&qs=n&form=QBIR&sp=-1&pq=%E7%A6%8F%E5%88%A9&sc=3-2&cvid=2AF12F93CAB34E8FBF902905B185583C&first=1&scenario=ImageBasicHover", "downloadImg/福利/");createTextDownloadThread("https://www.csdn.net/", "你", "Text/", "testText.txt");}//創建并執行線程,獲取圖片private static void createImageDownloadThread(String url, String path){new Thread(new DownloadPictures(url, path)).start();}//獲取文本內容private static void createTextDownloadThread(String urlStr, String findText, String downloadPath, String fileName){new Thread(new GetText(urlStr, findText, downloadPath, fileName)).start();}
}//DownloadPictures.java 爬取圖片類
package pers.baijiaming.download.main;import java.io.*; //io包
import java.util.regex.*; //正則包
import java.net.*; //網絡包/*
* 下載圖片類
* */
public final class DownloadPictures implements Runnable
{private URL url = null; //URLprivate URLConnection urlConn = null; //url連接private BufferedReader bufIn = null; //緩沖讀取器,讀取網頁信息private static final String IMG_REG = "<img.*srcs*=s*(.*?)[^>]*?>"; //img標簽正則private static final String IMG_SRC_REG = "srcs*=s*"?(.*?)("|>|s+)"; //img src屬性正則private String downloadPath = null; //保存路徑//構造,參數:想要下載圖片的網址、下載到的圖片存放的文件路徑public DownloadPictures(String urlStr, String downloadPath){createFolder(downloadPath); //創建文件夾try {url = new URL(urlStr);urlConn = url.openConnection();//設置請求屬性,有部分網站不加這句話會拋出IOException: Server returned HTTP response code: 403 for URL異常//如:b站urlConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");bufIn = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));}catch (Exception e) {e.printStackTrace();}this.downloadPath = downloadPath;}//檢測路徑是否存在,不存在則創建private void createFolder(String path){File myPath = new File(path);if (!myPath.exists()) //不存在則創建文件夾myPath.mkdirs();}//下載函數public void Download(){final int N = 20; //每一次處理的文本行數,這個數越小越容易遺漏圖片鏈接,越大效率越低 (理論上)String line = "";String text = "";while (line != null) //網頁內容被讀完時結束循環{for(int i = 0; i < N; i++) //讀取N行網頁信息存入到text當中,因為src內容可能分為多行,所以使用這種方法try {line = bufIn.readLine(); //從網頁信息中獲取一行文本if(line != null) //判斷防止把null也累加到text中text += line;}catch (IOException e) {e.printStackTrace();}//將img標簽正則封裝對象再調用matcher方法獲取一個Matcher對象final Matcher imgM = Pattern.compile(IMG_REG).matcher(text);if(!imgM.find()) //如果在當前text中沒有找到img標簽則結束本次循環continue;//將img src正則封裝對象再調用matcher方法獲取一個Matcher對象//用于匹配的文本為找到的整個img標簽final Matcher imgSrcM = Pattern.compile(IMG_SRC_REG).matcher(imgM.group());while (imgSrcM.find()) //從img標簽中查找src內容{String imageLink = imgSrcM.group(1); //從正則中的第一個組中得到圖片鏈接print(imageLink); //打印一遍鏈接//如果得到的src內容沒有寫協議,則添加上
// if(!imageLink.matches("https://[sS]*")) //這里有問題
// imageLink = "https://" + imageLink;print(imageLink); //打印一遍鏈接try{//緩沖輸入流對象,用于讀取圖片鏈接的圖片數據//在鏈接的圖片不存在時會拋出未找到文件異常final BufferedInputStream in = new BufferedInputStream(new URL(imageLink).openStream());//文件輸出流對象用于將從url中讀取到的圖片數據寫入到本地//保存的路徑為downloadPath,保存的圖片名為時間戳+".png"final FileOutputStream file = new FileOutputStream(new File(downloadPath + System.currentTimeMillis() + ".png"));int temp; //用于保存in從圖片連接中獲取到的數據while ((temp = in.read()) != -1)file.write(temp); //將數據寫入到本地路徑中//關閉流file.close();in.close();//下載完一張圖片后休息一會try {Thread.sleep(800);}catch (InterruptedException e) {e.printStackTrace();}}catch (Exception e){e.printStackTrace();}}//將text中的文本清空text = "";}}//run@Overridepublic void run(){Download(); //下載函數}//打印語句public void print(Object obj){System.out.println(obj);}
}//GetTest.java 爬取文本內容類
package pers.baijiaming.download.main;import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public final class GetText implements Runnable
{private URL url = null; //URLprivate URLConnection urlConn = null; //url連接private BufferedReader bufIn = null; //緩沖讀取器,讀取網頁信息// private static final String TEXT_REG = "([[[^x00-xff]|w]&&[^u003E]])+"; //文本內容正則private static final String TEXT_REG = "[[sS]&&[^<>n ]]*"; //文本內容正則,這里有些問題,試了很久,無法排除一個空格的情況
// <[a-zA-Z]+.*?>([sS]*?)</[a-zA-Z]*?>private String findText = null; //要查找的內容private String downloadPath = null; //保存路徑private String fileName = null; //文件名//構造,參數:url、要查找的文本、保存路徑,文件名public GetText(String urlStr, String findText, String downloadPath, String fileName){createFolder(downloadPath); //創建文件夾try {url = new URL(urlStr);urlConn = url.openConnection();//設置請求屬性,有部分網站不加這句話會拋出IOException: Server returned HTTP response code: 403 for URL異常//如:b站urlConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");bufIn = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));}catch (Exception e) {e.printStackTrace();}this.downloadPath = downloadPath;this.fileName = fileName;this.findText = findText;}//檢測路徑是否存在,不存在則創建private void createFolder(String path){File myPath = new File(path);if (!myPath.exists()) //不存在則創建文件夾myPath.mkdirs();}//下載函數private void Download(){final int N = 10;String line = "";String textStr = "";while (line != null){for(int i = 0; i < N; i++) //將N行內容追加到textStr字符串中try {line = bufIn.readLine();if(line != null)textStr += line;}catch (IOException e) {e.printStackTrace();}try{//將img標簽正則封裝對象再調用matcher方法獲取一個Matcher對象final Matcher textMatcher = Pattern.compile(TEXT_REG + findText + TEXT_REG).matcher(textStr);final FileWriter fw = new FileWriter(downloadPath + fileName, true); //文件編寫,續寫文件while (textMatcher.find()) //查找匹配文本{fw.write(textMatcher.group() + "n"); //寫入到文件中print(textMatcher.group()); //打印一遍}// print(textStr);fw.close();textStr = "";}catch (Exception e){e.printStackTrace();}}}//run@Overridepublic void run(){Download();}//打印語句private void print(Object obj){System.out.println(obj);}
}----
程序中還存在著許多問題,還請多多包涵。
總結
以上是生活随笔為你收集整理的循环爬取图片_Java爬取简单的网页内容和图片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我是年费怎么弄那个盘古坐骑
- 下一篇: 爱老婆微信网名大全