收錄方便以後參考
一、URLConnection入門
URLConnection代表應用程序和 URL 之間的通信鏈接。
創建一個到 URL 的連接需要幾個步驟:
1、通過在 URL 上調用 openConnection 方法創建連接對象。
URL url = new URL("http://localhost:8080/day04/1.html");
2、處理設置參數和一般請求屬性。
- 表示應用程序要將數據寫入 URL 連接,及發送數據
conn.setDoOutput(true); //默認false
- 表示應用程序要從 URL 連接讀取數據,及獲取數據
conn.setDoInput(true); //默認true
3、使用 connect 方法建立到遠程對象的實際連接。
conn.connect();
只是建立了一個與服務器的tcp連接,並沒有實際發送http請求
4、遠程對象變為可用。遠程對象的頭字段和內容變為可訪問。
conn.getOutputStream();
注意:
如果setDoOutput沒有設置true,會出現java.net.ProtocolException異常
getOutputStream會隱含的進行connect
conn.getInputStream();
注意: 在調用此方法之前以上所準備的數據僅緩存在本地內存中。調用了此方法將內存緩衝區中封裝好的完整的HTTP請求發送到服務端
package cn.itcast.url;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;
/**
* URLConnection簡單示例
* @author <a href="mailto:liangtong@itcast.cn">梁桐</a>
*/
public class UrlConnectionTest {
public static void main(String[] args) throws Exception{
//對指定的web鏈接進行描述
URL url = new URL("http://localhost:8080/day04/1.html");
//確定鏈接是否,獲得鏈接--鏈接否?
URLConnection conn = url.openConnection();
//設置參數
conn.setDoOutput(true); //默認false,是否可發送數據
conn.setDoInput(true); //默認true,是否可以接受數據
//鏈接
conn.connect();
//發送數據
OutputStream out = conn.getOutputStream(); //java.net.ProtocolException
out.write("username=rose".getBytes());
//獲得資源,並打印到控制枱
InputStream is = conn.getInputStream();
Scanner scanner = new Scanner(is);
while(scanner.hasNext()){
System.out.println(scanner.nextLine());
}
is.close();
out.close();
}
}
二、URLConnection--簡單爬蟲
上一節URLConnection入門 我們簡單的介紹了URLConnection類的使用。今天我們將在此基礎上完成一個小功能--爬蟲
原理:獲得下載資源,使用程序將此資源保存到本地
步驟:
1、分析下載站點
- 下載內容列表頁:http://sc.*.com/tubiao/index.html
- 下載內容詳細頁:/tubiao/120602202460.htm
- 下載地址: http://*.com/Files/download/icon3/4620.rar
2、通過程序實現以上分析過程,並獲得下載地址
- 使用循環獲得所有的下載列表頁的鏈接
- 通過鏈接將列表頁下載,並通過正則表達式,獲得當前列表頁中所有的詳細頁鏈接
- 下載詳細頁,仍通過正則表達式,獲得下載地址鏈接。
3、將內容保存到本地
通過下載地址鏈接,將需要下載的內容保存到本地
package cn.itcast.download;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 簡單爬蟲
* @author <a href="mailto:liangtong@itcast.cn">梁桐</a>
*/
public class ICOLoad {
public static void main(String[] args) throws Exception {
//遍歷測試站點的所有列表頁。測試站點列表頁的第一頁比較測試,所以單獨處理
for (int i = 1; i <= 266; i++) {
String url;
if (i == 1) {
url = "http://sc.*.com/tubiao/index.html";
} else {
url = "http://sc.*.com/tubiao/index_" + i + ".html";
}
System.out.println("################# " + url);
//獲得當前列表頁中,所有可用詳細頁鏈接
List<String> paths = ICOLoad.getPaths(url, 1);
for (String path : paths) {
System.out.println("獲取" + path);
//獲得當前詳細頁的指定的下載鏈接
List<String> downURLs = ICOLoad.getPaths(path, 2);
for (String downURL : downURLs) {
System.out.println("下載中 ..." + downURL);
// 下載
ICOLoad.downIcon(downURL);
System.out.println(downURL + "下載完成");
}
}
}
}
/**
* 通過給定的解析方法,解析需要的路徑
* @return
* @throws Exception
*/
public static List<String> getPaths(String url, int count) {
List<String> paths = new ArrayList<String>();
try {
URL icoUrl = new URL(url);
URLConnection conn = icoUrl.openConnection();
//測試網站使用的gb2312編碼
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "gb2312"));
String line = null;
while ((line = reader.readLine()) != null) {
//此處直接使用if簡化操作
// 處理列表頁面
if (count == 1) {
String path = findPath(line);
if (path != null) {
//列表頁中的詳細頁地址都是相對路徑,此處獲得完整路徑
String completeUrl = new URL(icoUrl, path).toString();
if (!paths.contains(completeUrl)) { // 過濾已有,測試網站圖標和鏈接出各有一個所需鏈接
paths.add(completeUrl);
}
}
}
// 處理下載地址
if (count == 2) {
String path = findDownURL(line);
if (path != null) {
paths.add(path);
}
}
}
reader.close();
return paths;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return paths;
}
/**
* 處理列表頁
* href="/tubiao/120602202460.htm"
*/
private static Pattern pathPattern = Pattern.compile(".*(/tubiao/[\\d]+.htm).*");
public static String findPath(String str) {
// String str = "<span><a target=\"_blank\" href=\"/tubiao/120524539010.htm\" alt=\"網站小圖標下載\">網站小圖標下載</a></span>";
Matcher matcher = pathPattern.matcher(str);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
/**
* 處理下載頁,僅下載icon頁面
* <a href="http://*.com/Files/DownLoad/icon/rw_11.rar">ICO中國網通下載</a>
* <a href="http://*.com/Files/download/icon3/4620.rar">ICO中國網通下載</a>
*/
private static Pattern downPattern = Pattern.compile(".*(http://*.com/.*icon.*.rar).*");
public static String findDownURL(String str) {
Matcher matcher = downPattern.matcher(str);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
/**
* 下載文件所在位置
*/
private static File downFile = new File("D:\\Image\\icoDown\\");
static {
if (!downFile.exists()) {
downFile.mkdirs();
}
}
/**
* 下載指定內容
* @param path
*/
public static void downIcon(String path) {
try {
URL url = new URL(path);
String icoFileUrl = url.getFile();
String fileName = getFileName(icoFileUrl.substring(1 + icoFileUrl
.lastIndexOf("/")));
File icoFile = new File(downFile + File.separator + fileName);
if (!icoFile.exists()) {
icoFile.createNewFile();
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
OutputStream out = new FileOutputStream(icoFile);
byte[] buf = new byte[1024];
int len = -1;
while ((len = is.read(buf)) > -1) {
out.write(buf, 0, len);
}
out.close();
is.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 獲得下載文件本地名稱,如果重名自動加1
* @param fileName
* @return
*/
public static String getFileName(String fileName) {
File file = new File(downFile + File.separator + fileName);
if (file.exists()) {
String fileNum = fileName.substring(0, fileName.indexOf("."));
Integer num = Integer.valueOf(fileNum);
return getFileName((num + 1) + ".rar");
}
return fileName;
}
}