Java實現(xiàn)網(wǎng)絡數(shù)據(jù)提取所需知識點
本篇對一些常用的java知識做一個整合,三大特性、IO操作、線程處理、類集處理,目的在于能用這些只是實現(xiàn)一個網(wǎng)頁爬蟲的功能。
Ⅰ 首先對于一個java開發(fā)的項目有一個整體性的了解認知,項目開發(fā)流程:
項目階段:
1)項目準備:
a)根據(jù)開會得到會議紀要,了解客戶的需求情況
b)需求分析(需求分析文檔)
c)數(shù)據(jù)庫設計和網(wǎng)站(產品)原型設計
d)架構設計
2)項目開發(fā)
a)項目組長(PM,PL)進行項目的時間規(guī)劃,并劃分好每個人的工作任務
b)程序員主要完成項目代碼編寫和詳細設計文檔編寫。(用戶手冊)
3)測試
a)單元測試
b)集成測試
c)壓力測試
d)回歸測試
4)上線實施
Ⅱ 三大特性(封裝、繼承、多態(tài))
封裝
1、 封裝重點在于一個private關鍵字,目的是為了讓類中的屬性不能直接修改或取得。也就是說,建立一個類時,所有的屬性都必須通過private進行封裝。
既然屬性被封裝了,那么如果想設置或取得屬性,就必須編寫getter/setter方法。
同時,類中在創(chuàng)建對象時,為了方便,一般建議編寫一些帶參數(shù)的構造方法。
如果不編寫構造方法,程序會自動加入一個無參的構造,但是,如果自己聲明了構造方法,那么必須就手工加入一個無參構造,為了讓其他的框架可以通過無參數(shù)構造來創(chuàng)建對象。
2、 如果數(shù)據(jù)庫中有一張表,則需要你能根據(jù)表編寫一個這樣的類。
這種類被稱為:VO(Value Object)、TO(Transfer Object)、POJO(Plain Olds Java Object)、DTO(DaTa Object)等
class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
技巧:在eclipse中編寫封裝類,可以聲明變量后,按shift+Alt+s鍵出現(xiàn)Generate Getters and Setters提示創(chuàng)建getter和setter方法。

繼承關系
繼承所使用的關鍵字:extends,接口實現(xiàn)所使用的關鍵字是:implements。
Java開發(fā)中對于接口和抽象類區(qū)別主要是單繼承和多繼承。
真正開發(fā)中接口用的更多,幾乎不編寫抽象類。
一般都是以接口作為標準來進行聲明。
這部分我們要求能夠掌握接口的聲明和實現(xiàn)方法。
interface Animal {
public void cry();
public void run();
}
class Cat implements Animal {
@Override
public void cry() {
System.out.println("miao");
}
@Override
public void run() {
System.out.println("貓爬樹");
}
}
多態(tài)
其實就是在繼承的基礎上進行方法覆寫和子類轉型。
package org.liky.test;
public class InterfaceDemo {
public static void main(String[] args) {
Animal a1 = new Cat();
Animal a2 = new Dog();
a1.cry();
a2.cry();
}
}
interface Animal {
public void cry();
public void run();
}
class Cat implements Animal {
@Override
public void cry() {
System.out.println("miao");
}
@Override
public void run() {
System.out.println("貓爬樹");
}
}
class Dog implements Animal {
@Override
public void cry() {
System.out.println("Wang");
}
@Override
public void run() {
System.out.println("狗游泳");
}
}
單例設計模式
單例模式有以下特點:
1、單例類只能有一個實例。
2、單例類必須自己創(chuàng)建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
package org.liky.test;
public class TestSingleton {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
Singleton s3 = Singleton.getInstance();
//其實只創(chuàng)建了一個對象
System.out.println(s1 + " --> " + s2 + " --> " + s3);
}
}
class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
Ⅲ IO操作
文件內容讀?。?/p>
File、FileReader、FileWriter、BufferedReader、BufferedWriter、Scanner、InputStreamReader
文件夾遍歷:
File
文件復制操作
如果想操作文件的內容(對內容進行寫出和讀?。枰褂玫降木褪荌O流中的輸入輸出操作。
這種輸入和輸出的操作流有兩種:
1)字符流:主要操作文本文件(編寫爬蟲操作時,肯定要使用字符流來完成)
a)讀:FileReader
b)寫:FileWriter
2)字節(jié)流:所有文件都可以使用這種流操作
a)讀:InputStream
b)寫:OutputStream
需要能夠通過我們這里的FileReader和FileWriter配合文件類:File,完成內容的讀取和寫出。
/**
* IO流操作的演示類,用來演示文本文件的寫出和讀取
*
* @author Liky
*
*/
public class FileTest {
public static void main(String[] args) {
// 寫出內容
// writeData(
// "D:/test.txt",
// "這是“吉林一號”視頻衛(wèi)星 8月9日11時25分拍攝的 九寨溝縣視頻 顯示了九寨溝縣的地形地貌 縣城呈狹長分布 周邊山體有明顯滑坡痕跡 視頻中還可見縣城道路大部分完好 有車輛通行 一架飛機飛過 地面與空中交通并未中斷 圖像提供:長光衛(wèi)星技術有限公司 技術支持:北京愛太空科技發(fā)展有限公司");
System.out.println(readData("D:/test.txt"));
}
/**
* 寫出數(shù)據(jù)
*
* @param filePath
* 文件保存的位置
* @param data
* 要保存的文件內容數(shù)據(jù)
*/
public static void writeData(String filePath, String data) {
// 先有一個文件,來保存要寫出的數(shù)據(jù)
File file = new File(filePath);
// 建立輸出流對象
try {
FileWriter writer = new FileWriter(file);
// 開始完成內容的輸出
writer.write(data);
// 資源必須回收,也就是必須將流關閉
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 讀取數(shù)據(jù)
*
* @param filePath
* 要讀取的文件所在的完整路徑
* @return 讀取出來的文檔內容
*/
public static String readData(String filePath) {
// 也要建立文件對象
File file = new File(filePath);
// 建立讀取的輸入流對象
try {
FileReader reader = new FileReader(file);
// 每次調用read可以讀取一個字符,
// 按照int類型返回,返回的是字符的編碼,
// 需要通過強制類型轉換,變?yōu)閏har類型
// Java中對于String這個類一般不建議反復修改,因為會占用內存。
StringBuilder builder = new StringBuilder();
// 因為文件中有很多的字符,因此需要循環(huán)來進行內容的讀取。
// 就需要判斷是否還有字符進行讀取
int value = -1;
// 每次讀取時,如果讀到內容,則會返回 0 - 65535 的char類型字符
// 如果沒有讀取到內容,則返回 -1 ,因此我們可以根據(jù)這個 -1 來判斷后面是否還有內容
while ((value = reader.read()) != -1) {
// 將讀取到的內容保存下來
char c = (char) value;
// 把字符放入到StringBuilder里
builder.append(c);
}
// 沒有讀取到內容,說明循環(huán)結束,已經到了文件的末尾
return builder.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
目前這樣編寫已經可以實現(xiàn)內容的輸入和輸出操作了。
但是還不支持換行操作,如果想換行,需要人工進行\(zhòng)r\n的編寫。
如果不想人工編寫換行,就可以使用以下兩個類來完成輸入。
PrintWriter(打印流)
BufferedWriter(緩沖流)
public static void writeData(String filePath, String... data) {
// 先有一個文件,來保存要寫出的數(shù)據(jù)
File file = new File(filePath);
// 建立輸出流對象
try {
// FileWriter writer = new FileWriter(file);
PrintWriter pw = new PrintWriter(file);
// 開始完成內容的輸出
for (String str : data) {
pw.println(str);
}
// 資源必須回收,也就是必須將流關閉
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
使用時,注意我們這里加入了可變參數(shù)來動態(tài)傳入多個字符串(即String... data)。
當讀取數(shù)據(jù)時,如果我們使用普通的讀取方式,對于換行的處理不方便。
如果想按行讀取內容,可以使用BufferedReader,Scanner
Scanner是JDK1.5新的
BufferedReader是JDK1.0就有的,所以使用BufferedReader。
為什么現(xiàn)在還使用BufferedReader,因為Scanner不支持編碼的轉換。
public static String readData(String filePath) {
// 也要建立文件對象
File file = new File(filePath);
// 建立讀取的輸入流對象
try {
FileReader reader = new FileReader(file);
BufferedReader bw = new BufferedReader(reader);
// 每次調用read可以讀取一個字符,
// 按照int類型返回,返回的是字符的編碼,
// 需要通過強制類型轉換,變?yōu)閏har類型
// Java中對于String這個類一般不建議反復修改,因為會占用內存。
StringBuilder builder = new StringBuilder();
// 因為文件中有很多的字符,因此需要循環(huán)來進行內容的讀取。
// 就需要判斷是否還有字符進行讀取
String line = null;
// 每次讀取時,如果讀到內容,則會返回 0 - 65535 的char類型字符
// 如果沒有讀取到內容,則返回 -1 ,因此我們可以根據(jù)這個 -1 來判斷后面是否還有內容
while ((line = bw.readLine()) != null) {
// 將讀取到的內容保存下來
// 把字符放入到StringBuilder里
builder.append(line);
System.out.println(line);
}
// 沒有讀取到內容,說明循環(huán)結束,已經到了文件的末尾
return builder.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
例如,將一個D盤的test.txt的內容讀取出來,再寫出到E盤的test.txt中
public static void copyFile(String inputFile, String outputPath) {
// 首先建立輸入和輸出的文件
File input = new File(inputFile);
File output = new File(outputPath);
// 建立輸入和輸出流
try {
BufferedReader br = new BufferedReader(new FileReader(input));
PrintWriter pw = new PrintWriter(output);
// 每次讀入一行,所以準備一個變量來接收
String line = null;
while ((line = br.readLine()) != null) {
pw.println(line);
}
pw.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
文件夾迭代
這里只需要用到一個File類,但需要用里面的一些方法來判斷是文件還是文件夾
isFile():是否是文件
isDirectory():是否是文件夾
還需要通過遞歸操作,將目錄下的所有子目錄也進行迭代。
多線程處理
使用多線程的目的肯定是為了提升程序的效率。
因為在進行網(wǎng)絡數(shù)據(jù)爬取時,一般都是同時爬取多個網(wǎng)頁的數(shù)據(jù),而不是單個網(wǎng)頁,因此在項目開發(fā)中我們需要通過多線程,來讓程序同時完成多個操作。
多線程有兩種實現(xiàn)方式:
1)繼承Thread類
2)實現(xiàn)Runnable接口
使用多線程時,還有兩個必須注意的方法:
1)start()啟動線程
2)run()編寫線程執(zhí)行的主體。
先來完成一個倒計時功能:
public class ThreadDemo {
public static void main(String[] args) {
// new MyThread().start();
// new Thread() {
// public void run() {
// for (int i = 10; i >= 0; i--) {
// System.out.println("剩余時間:" + i);
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }
// }.start();
// new Thread(new MyRunnable()).start();
}
}
//繼承Thread類必須重寫run類
class MyThread extends Thread {
@Override
public void run() {
for (int i = 10; i >= 0; i--) {
System.out.println("剩余時間:" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 10; i >= 0; i--) {
System.out.println("剩余時間:" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
類集處理
List:允許重復,可以根據(jù)下標來取得數(shù)據(jù),會按照放入的順序來存儲數(shù)據(jù)。
ArrayList:以數(shù)組的形式存儲,適合不經常變動,但經常查詢的數(shù)據(jù)集。
LinkedList:以鏈表的形式存儲,適合經常變動的數(shù)據(jù)集,但是不經常查詢
public class ListDemo {
public static void main(String[] args) {
LinkedList<Integer> list1 = new LinkedList<>();
for (int i = 0; i <= 100000; i++) {
list1.add(i);
}
long start = System.currentTimeMillis();
for (int i = 0; i <= 100000; i++) {
list1.get(i);
}
long end = System.currentTimeMillis();
System.out.println("ArrayList: " + (end - start) + " ms");
}
}
Set:不允許重復,存儲順序看心情,沒辦法根據(jù)下標取得數(shù)據(jù)
HashSet:散列排序(沒有順序)
TreeSet:二叉樹排序,按照固定的規(guī)則來排序,TreeSet中的內容必須實現(xiàn)一個Comparable的接口,并且必須覆寫compareTo的方法,根據(jù)給定的規(guī)則來排序。
public class SetDemo {
public static void main(String[] args) {
Set<Person> set = new TreeSet<>();
set.add(new Person("張三", 12));
set.add(new Person("李四", 22));
set.add(new Person("王五", 42));
set.add(new Person("王八", 42));
set.add(new Person("趙六", 32));
System.out.println(set);
}
}
class Person implements Comparable<Person> {
private String name;
private Integer age;
public Person() {
super();
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Person o) {
if (this.age > o.age) {
return 1;
} else if (this.age < o.age) {
return -1;
}
if (this.name.equals(o.name)) {
return 0;
}
return 1;
}
}
Map:key-value形式,可以根據(jù)key取得value,key按照Set集合的模式來保存。
HashMap:散列
TreeMap:有順序
對于Map集合,要求能夠循環(huán)迭代出里面的所有數(shù)據(jù)。
所以必須掌握Map的循環(huán)方法。
public class MapDemo {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("方便面", 20);
map.put("火腿腸", 120);
map.put("礦泉水", 20);
map.put("可樂", 30);
// Map集合如果想迭代必須先按照key來進行迭代,
// 再根key查找value
Set<String> keySet = map.keySet();
for (String key : keySet) {
System.out.println(key + " ---> " + map.get(key));
}
}
}
小結:
本篇對于java封裝、繼承、多態(tài)三大特性,IO操作,線程管理,類集處理(List、Set、Map)進行了闡述以及代碼實現(xiàn)。
到此,對于網(wǎng)頁數(shù)據(jù)的爬寫的知識準備的可以了,下一篇我會先對一個文件進行數(shù)據(jù)爬取,然后再對網(wǎng)頁上的數(shù)據(jù)代碼實現(xiàn)爬蟲功能
到此這篇關于Java實現(xiàn)網(wǎng)絡數(shù)據(jù)提取所需知識點的文章就介紹到這了,更多相關Java實現(xiàn)網(wǎng)絡數(shù)據(jù)提取內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
配置pom.xml用maven打包java工程的方法(推薦)
下面小編就為大家?guī)硪黄渲胮om.xml用maven打包java工程的方法(推薦)。小編覺得挺不錯的, 現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06
Javaweb實戰(zhàn)之實現(xiàn)蛋糕訂購系統(tǒng)
隨著網(wǎng)絡的普及與發(fā)展,網(wǎng)上購物逐漸成為一種主流消費的方式。這篇文章主要介紹了通過JavaWeb制作一個線上蛋糕訂購系統(tǒng),文中示例代碼講解詳細,需要的朋友可以參考一下2021-12-12
Spring Boot中@RequestParam參數(shù)的5種情況說明
這篇文章主要介紹了Spring Boot中@RequestParam參數(shù)的5種情況說明,具有很好的參考價值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
日常開發(fā)中,我們很多時候需要用到Java?8的Lambda表達式,它允許把函數(shù)作為一個方法的參數(shù),讓我們的代碼更優(yōu)雅、更簡潔。所以整理了一波工作中常用的Lambda表達式??赐暌欢〞袔椭?/div> 2022-11-11最新評論

