《網頁爬蟲》
1.初始版本
package com.zyjl.crawler;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/**
* 爬取網路資源的類(網路爬蟲)
* 一級(通過httpclient和jsoup爬取網頁,分析所有url)
* @author Administrator
*
*/
public class StartCrawler01 {
/**
* 解析URL(通過網址URL,利用httpclient技術,獲取當前URL對應的網路內容)
* @param url
*/
public static void parseUrl(String url,String realDir) {
CloseableHttpClient HttpClient = HttpClients.createDefault(); //獲取httpclient的例項
HttpGet httpGet = new HttpGet(url); //設定提交方式:get
CloseableHttpResponse response = null;
try {
response = HttpClient.execute(httpGet); //執行
HttpEntity entity = response.getEntity(); //獲取內容
// System.out.println(entity.getContentType().toString()); //Content-Type: text/html
// System.out.println(entity.getContentType().getName()); //Content-Type
// System.out.println(entity.getContentType().getValue()); //text/html
//如果是text/html型別的URL,需要再次解析
if("text/html".equals(entity.getContentType().getValue())) {
String pageContent = EntityUtils.toString(entity,"utf-8"); //獲取網頁內容
// System.out.println("網頁內容:"+pageContent);
parsePageContent(pageContent, realDir); //通過網頁爬蟲框架jsoup解析網頁內容的方法
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//關閉response資源
if(response != null) {
response.close();
}
//關閉HttpClient資源
if(HttpClient != null) {
HttpClient.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 通過網頁爬蟲框架jsoup對網頁內容進行解析
* @param pageContent
*/
public static void parsePageContent(String pageContent, String realDir) {
Document doc = Jsoup.parse(pageContent); //獲取jsp的dom樹
Elements aEles = doc.select("a"); //通過選擇器獲取dom樹的所有a標籤
for (Element aEle : aEles) {
String aUrl = aEle.attr("href"); //獲取a標籤的href
System.out.println("URL:"+realDir+aUrl);
// Element after = aEle.after("href");
// System.out.println("aHref:"+after);
}
}
/**
* 程式入口
* @param args
*/
public static void main(String[] args) {
String url="http://central.maven.org/maven2/HTTPClient/HTTPClient/";
parseUrl(url,url);
}
}
2,第一步(過濾)優化
package com.zyjl.crawler;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/**
* 爬取網路資源的類(網路爬蟲)
* 二級(過濾無效url,迭代解析)
* @author Administrator
*
*/
public class StartCrawler02 {
//堆列:先進先出(堆疊:先進後出)
public static String[] excludeUrls = new String[] { ".pom", ".xml", ".md5", ".sha1", ".asc", ".gz", ".zip", "../" }; // 要過濾的url字尾
public static Queue<String> waitForCrawlerUrls = new LinkedList<String>();// 等待再次爬取的Url
public static long total = 0; //計算第n條被爬取的連結
/**
* 解析URL(通過網址URL,利用httpclient技術,獲取當前URL對應的網路內容)
* @param url
*/
public static void parseUrl() {
while(waitForCrawlerUrls.size()>0) {
String URL = waitForCrawlerUrls.poll(); //摘取佇列的第一個元素,並且移除
CloseableHttpClient HttpClient = HttpClients.createDefault(); //獲取httpclient的例項
HttpGet httpGet = new HttpGet(URL); //設定提交方式:get
CloseableHttpResponse response = null;
try {
response = HttpClient.execute(httpGet); //執行
HttpEntity entity = response.getEntity(); //獲取內容
//如果是text/html型別的URL,需要再次解析
if("text/html".equals(entity.getContentType().getValue())) {
String pageContent = EntityUtils.toString(entity,"utf-8"); //獲取網頁內容
//System.out.println("網頁內容:"+pageContent);
parsePageContent(pageContent, URL); //通過網頁爬蟲框架jsoup解析網頁內容的方法
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//關閉response資源
if(response != null) {
response.close();
}
//關閉HttpClient資源
if(HttpClient != null) {
HttpClient.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 通過網頁爬蟲框架jsoup對網頁內容進行解析
* @param pageContent
*/
public static void parsePageContent(String pageContent, String realDir) {
Document doc = Jsoup.parse(pageContent); //獲取jsp的dom樹
Elements aEles = doc.select("a"); //通過選擇器獲取dom樹的所有a標籤
long i = 0; //計算讀取所有連結的第幾條
for (Element aEle : aEles) {
String aHref = aEle.attr("href"); //獲取a標籤的href
String URL = realDir+aHref; //所有連結
if(i == 0) {
System.out.println("\r"+"開始爬取新的網頁..."+"\r");
}
System.out.println("爬取到第"+(++i)+"條連結:"+URL);
/**
* 1:目標連結
* 2:需要過濾掉的連結
* 3:需要迭代解析的連結
*/
if(URL == null || URL.equals("")) return; //如果URL為空,就return掉
boolean f = true; //預設就是符合要求的目標連結
for (String excludeUrl : excludeUrls) { //遍歷迴圈需要過濾掉的連結字尾
if(URL.endsWith(excludeUrl)) { //如果與連結字尾匹配,就返回false(過濾掉)
f = false;
break; //停止
}
}
if(f && URL.endsWith(".jar")) { //是否需要迭代解析的連結
System.err.println("\r"+"爬取的第"+(++total)+"條目標連結,URL:"+URL+"\r");
}else { //需要再次迭代爬取的連結
addUrl(URL);
}
}
}
/**
* 新增到爬蟲佇列,等待再次爬取
* @param URL
*/
private static void addUrl(String URL) {
System.out.println("連結:"+URL+"被新增到了爬蟲 佇列");
waitForCrawlerUrls.add(URL);
}
/**
* 初始化方法
*/
private static void init() {
String URL="http://central.maven.org/maven2/HTTPClient/HTTPClient/";
addUrl(URL);
addUrl("http://central.maven.org/maven2/commons-cli/commons-cli/");
parseUrl();
}
/**
* 程式入口
* @param args
*/
public static void main(String[] args) {
init();
}
}
3.效能優化
package com.zyjl.crawler;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/**
* 爬取網路資源的類(網路爬蟲)
* 三級(利用非同步執行緒池對爬取的效能進行優化)
* @author Administrator
*
*/
public class StartCrawler03 {
//堆列:先進先出(堆疊:先進後出)
public static String[] excludeUrls = new String[] { ".pom", ".xml", ".md5", ".sha1", ".asc", ".gz", ".zip", "../" }; // 要過濾的url字尾
public static Queue<String> waitForCrawlerUrls = new LinkedList<String>();// 等待再次爬取的Url
public static long total = 0; //計算第n條被爬取的連結
public static boolean exeFlag = true; //預設解析爬蟲佇列中的網址URL
/**
* 解析URL(通過網址URL,利用httpclient技術,獲取當前URL對應的網路內容)
*/
public static void parseUrl() {
ExecutorService service = Executors.newFixedThreadPool(10); //建立執行緒池(存放了10個非同步執行緒)
while(exeFlag) { //正在執行爬蟲列隊
if(waitForCrawlerUrls.size()>0) { //如果有等待再次爬取的Url,就執行以下邏輯
//使用執行緒池中的非同步執行緒執行解析邏輯
service.execute(new Runnable() {
public void run() {
// TODO Auto-generated method stub
while(waitForCrawlerUrls.size()>0) { //如果堆列waitForCrawlerUrls中有等待再次爬取的Url
String URL = waitForCrawlerUrls.poll(); //摘取佇列的第一個元素,並且移除
CloseableHttpClient HttpClient = HttpClients.createDefault(); //獲取httpclient的例項
HttpGet httpGet = new HttpGet(URL); //設定提交方式:get
//設定配置(連線時長:8秒,等待伺服器響應資料時長:10秒)
RequestConfig config = RequestConfig.custom().setConnectTimeout(8000).setSocketTimeout(10000).build();
httpGet.setConfig(config);
CloseableHttpResponse response = null;
try {
response = HttpClient.execute(httpGet); //執行
if(response != null) {
HttpEntity entity = response.getEntity(); //獲取內容
//如果是text/html型別的URL,需要再次解析
if("text/html".equals(entity.getContentType().getValue())) {
String pageContent = EntityUtils.toString(entity,"utf-8"); //獲取網頁內容
//System.out.println("網頁內容:"+pageContent);
parsePageContent(pageContent, URL); //通過網頁爬蟲框架jsoup解析網頁內容的方法
}
}else {
System.err.println("連結時間過長!!!");
addUrl(URL); //將連結URL重新加到爬蟲佇列
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//關閉response資源
if(response != null) {
response.close();
}
//關閉HttpClient資源
if(HttpClient != null) {
HttpClient.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}else { //如果沒有等待再次爬取的Url
//獲取正在執行爬蟲任務的執行緒數
if(((ThreadPoolExecutor)service).getActiveCount() == 0) { //如果執行緒數為0,就關閉
exeFlag = false;
break;
}
}
}
try {
Thread.sleep(1500);//休眠1.5s是為了,給執行緒解析網頁網頁的時間,不然容易出現問題
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 通過網頁爬蟲框架jsoup對網頁內容進行解析
*
* 1:獲取所有目標連結
* 2:過濾掉不符合要求的連結
* 3:拿到需要迭代解析符合要求的目標連結
* @param pageContent
*/
public static void parsePageContent(String pageContent, String realDir) {
// * 1:獲取所有目標連結
Document doc = Jsoup.parse(pageContent); //獲取jsp的dom樹
Elements aEles = doc.select("a"); //通過選擇器獲取dom樹的所有a標籤
long i = 0; //計算讀取當前網頁所有連結的第幾條
for (Element aEle : aEles) {
String aHref = aEle.attr("href"); //獲取a標籤的href
String URL = realDir+aHref; //所有連結
if(i == 0) {
System.out.println("\r"+"開始爬取新的網頁..."+"\r");
}
System.out.println("讀取到第"+(++i)+"條連結:"+URL);
// * 2:過濾掉不符合要求的連結
if(URL == null || URL.equals("")) return; //如果URL為空,就return掉
boolean f = true; //預設就是符合要求的目標連結
for (String excludeUrl : excludeUrls) { //遍歷迴圈需要過濾掉的連結字尾(過濾所有不符合要求的連結)
if(URL.endsWith(excludeUrl)) { //如果與連結字尾匹配,就返回false(過濾掉)
f = false;
break; //停止
}
}
//* 3:拿到需要迭代解析符合要求的目標連結
if(f && URL.endsWith(".jar")) { //如果是符合要求需要迭代解析的連結
System.err.println("\r"+"爬取到第"+(++total)+"條目標連結,URL:"+URL+"\r");
}else { //如果不是,新增到爬蟲列隊,再次迭代爬取的連結
addUrl(URL);
}
}
}
/**
* 新增到爬蟲佇列,等待再次爬取
* @param URL
*/
private static void addUrl(String URL) {
waitForCrawlerUrls.add(URL);
System.out.println("連結:"+URL+"被新增到了爬蟲 佇列");
}
/**
* 初始化方法
*/
private static void init() {
String URL="http://central.maven.org/maven2/HTTPClient/HTTPClient/";
addUrl(URL);
addUrl("http://central.maven.org/maven2/commons-cli/commons-cli/");
parseUrl();
}
/**
* 程式入口
* @param args
*/
public static void main(String[] args) {
init();
}
}
相關文章
- 爬蟲——網頁爬取方法和網頁解析方法爬蟲網頁
- python爬蟲---網頁爬蟲,圖片爬蟲,文章爬蟲,Python爬蟲爬取新聞網站新聞Python爬蟲網頁網站
- wget 網頁爬蟲,網頁抓取工具wget網頁爬蟲
- node:爬蟲爬取網頁圖片爬蟲網頁
- 網頁爬蟲--未完成網頁爬蟲
- python 爬蟲網頁登陸Python爬蟲網頁
- 爬蟲抓取網頁資料原理爬蟲網頁
- 【爬蟲】網頁抓包工具--Fiddler爬蟲網頁
- 爬蟲抓取網頁的詳細流程爬蟲網頁
- Python爬蟲之網頁圖片Python爬蟲網頁
- golang解析網頁,可以做爬蟲了Golang網頁爬蟲
- Java爬蟲翻頁Java爬蟲
- 一起學爬蟲——使用Beautiful Soup爬取網頁爬蟲網頁
- Node JS爬蟲:爬取瀑布流網頁高清圖JS爬蟲網頁
- Python爬蟲使用代理proxy抓取網頁Python爬蟲網頁
- 爬蟲(6) - 網頁資料解析(2) | BeautifulSoup4在爬蟲中的使用爬蟲網頁
- 不會Python爬蟲?教你一個通用爬蟲思路輕鬆爬取網頁資料Python爬蟲網頁
- 手把手教你利用爬蟲爬網頁(Python程式碼)爬蟲網頁Python
- 網路爬蟲——爬蟲實戰(一)爬蟲
- python爬蟲:使用BeautifulSoup修改網頁內容Python爬蟲網頁
- 【爬蟲】網頁抓包工具--Charles的使用教程爬蟲網頁
- Python爬蟲教程-13-爬蟲使用cookie爬取登入後的頁面(人人網)(下)Python爬蟲Cookie
- Python爬蟲教程-12-爬蟲使用cookie爬取登入後的頁面(人人網)(上)Python爬蟲Cookie
- 網路爬蟲-去除網頁原始碼中的標籤爬蟲網頁原始碼
- python 爬蟲如何爬取動態生成的網頁內容Python爬蟲網頁
- 網路爬蟲爬蟲
- Python網路爬蟲之爬取淘寶網頁頁面 MOOC可以執行的程式碼Python爬蟲網頁
- Python靜態網頁爬蟲專案實戰Python網頁爬蟲
- 001.01 一般網頁爬蟲處理網頁爬蟲
- 爬蟲:如何判斷一個網頁已經更新?爬蟲網頁
- Jsoup + HtmlUtil 實現網易新聞網頁爬蟲JSHTML網頁爬蟲
- Python 爬蟲網頁內容提取工具xpath(一)Python爬蟲網頁
- Python 爬蟲網頁解析工具lxml.html(二)Python爬蟲網頁XMLHTML
- Python 爬蟲網頁解析工具lxml.html(一)Python爬蟲網頁XMLHTML
- Python3 | 簡單爬蟲分析網頁元素Python爬蟲網頁
- Python 爬蟲網頁內容提取工具xpath(二)Python爬蟲網頁
- LLM實戰:當網頁爬蟲整合gpt3.5網頁爬蟲GPT
- [網路爬蟲]使用node.js cheerio抓取網頁資料爬蟲Node.js網頁