目的:
通過網絡爬蟲爬取中國最小粒度的區域維度信息,包括省(Province) 、市(City)、縣(County)、鎮(town)、村委會(village)
主網站鏈接:
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2015/index.html
主要jar包:
http://jsoup.org/packages/jsoup-1.8.1.jar
之前一節我們說過java爬蟲從網絡上利用jsoup獲取網頁文本,也就是說我們可以有三種方法獲取html,一是根據url鏈接,而是從本地路徑獲取,三是通過字符串解析成html文檔
在這里,我們利用前兩種搭配使用:
先看本地是否存在需要的網頁,如果不存在就通過url獲取並保存在本地(下次就可以不需要重新從網絡加載)
我們先建一個類叫做Html類,具體內容如下:
package Product; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import org.jsoup.*; import org.jsoup.nodes.*; import org.jsoup.select.*; public class Html { //根據url從網絡獲取網頁文本 public Document getHtmlTextByUrl(String url) { Document doc = null; try { //doc = Jsoup.connect(url).timeout(5000000).get(); int i = (int) (Math.random()*1000); //做一個隨機延時,防止網站屏蔽
while(i!=0)
{ i--; }
doc= Jsoup.connect(url).data("query", "Java")
.userAgent("Mozilla") .cookie("auth", "token")
.timeout(300000) .post();
} catch (IOException e)
{ e.printStackTrace();
try {
doc = Jsoup.connect(url).timeout(5000000).get();
}
catch (IOException e1)
{ // TODO Auto-generated catch block e1.printStackTrace(); } }
return doc;
}
//根據本地路徑獲取網頁文本,如果不存在就通過url從網絡獲取並保存
public Document getHtmlTextByPath(String name,String url)
{
String path = "D:/Html/" +name+".html";
Document doc = null ;
File input = new File(path);
String urlcat = url;
try {
doc = Jsoup.parse(input, "GBK");
if(!doc.children().isEmpty())
{
doc=null; System.out.println("已經存在"); }
}
catch (IOException e)
{
System.out.println("文件未找到,正在從網絡獲取.......");
doc = this.getHtmlTextByUrl(url);
//並且保存到本地
this.Save_Html(url, name); } return doc; } //此處為保存網頁的函數
//將網頁保存在本地(通過url,和保存的名字) public void Save_Html(String url,String name) { try { name = name+".html"; // System.out.print(name); File dest = new File("D:/Html/" +name);//D:\Html //接收字節輸入流 InputStream is; //字節輸出流 FileOutputStream fos = new FileOutputStream(dest); URL temp = new URL(url); is = temp.openStream(); //為字節輸入流加緩沖 BufferedInputStream bis = new BufferedInputStream(is); //為字節輸出流加緩沖 BufferedOutputStream bos = new BufferedOutputStream(fos); int length; byte[] bytes = new byte[1024*20]; while((length = bis.read(bytes, 0, bytes.length)) != -1){ fos.write(bytes, 0, length); } bos.close(); fos.close(); bis.close(); is.close(); } catch (IOException e) { e.printStackTrace(); } }
這樣通過Html這個類,調用getHtmlTextByPath函數,傳入我們的鏈接和想要保存的名稱,接下就可以對這個網頁文本提取信息
並將整個網頁下載到我們的本地。
看到我們的網站是這樣的:

利用谷歌瀏覽右鍵檢查元素,我們注意觀察黃色標記的部分:

我們發現這些文本信息和超鏈接信息在tr 下的td下的a標簽內,利用我們的jsoup可以直接獲取到這些信息,詳情請看:
//根據元素屬性獲取某個元素內的elements列表 public Elements getEleByClass(Document doc,String className) { Elements elements= null;
elements = doc.select(className);//這里把我們獲取到的html文本doc,和工具class名,注意<tr class="provincetr">
return elements; //此處返回的就是所有的tr集合
}
我們在調用的時候,就直接把我們獲取的html文本,以及"tr.provincertr"作為參數傳入,在來解析tr集合內部的信息,
也就是td中兩個a標簽href和文本內容:比如href="12.html" 北京
代碼如下:
//獲取省 、市 、縣等的信息 public ArrayList getProvince(String name,String url ,String type) { ArrayList result= new ArrayList(); //"tr.provincetr" String classtype = "tr."+type+"tr"; //從網絡上獲取網頁 // Document doc = this.getHtmlTextByUrl(url); //從本地獲取網頁,如果沒有則從網絡獲取 Document doc2 = this.getHtmlTextByPath(name,url); System.out.println(name); if(doc2!=null){ Elements es =this.getEleByClass(doc2,classtype); //tr的集合 for(Element e : es) //依次循環每個元素,也就是一個tr { if(e!=null){ for(Element ec : e.children()) //一個tr的子元素td,td內包含a標簽 { String[] prv = new String[4]; //身份的信息: 原來的url(當前url) 名稱(北京) 現在url(也就是北京的url) 類型(prv)省 if(ec.children().first()!=null) { //原來的url prv[0]=url; //就是參數url //身份名稱 System.out.println(ec.children().first().ownText()); prv[1]=ec.children().first().ownText(); //a標簽文本 如:北京 //身份url地址 //System.out.println(ec.children().first().attr("href")); //http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2015/index.html String ownurl=ec.children().first().attr("abs:href"); //北京的url //因為如果從本地取得話,會成為本地url,所以保留第一次從網絡上的url,保證url不為空 if(ownurl.length()<10) { connectOrcl c = new connectOrcl(); ownurl = c.selectOne(prv[1]); //從數據庫中取,這是另一個調用數據庫函數,根據名稱取url } prv[2]=ownurl; //如:北京自己的url System.out.println(prv[2]); //級別 prv[3]=type; //就是剛剛傳的類型,后面會有city 、county等 //將所有身份加入list中 result.add(prv);} }} } } return result; //反回所有的省份信息集合,存數據庫,字段類型為: baseurl name ownurl levelname(type) updatetime }
java獲取本機的名稱和ip
//獲取本機名稱和IP
public static void main(String[] args) { InetAddress ia=null; try { ia = ia.getLocalHost(); String localname=ia.getHostName(); String localip=ia.getHostAddress(); System.out.println("本機名稱是:"+ localname); System.out.println("本機的ip是 :"+localip); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
java獲取本機的屏幕分辨率,DPI,以及屏幕尺寸
屏幕分辨率:比如1366*768
DPI:意思是說一英寸多少個象素
屏幕的物理尺寸:屏幕的物理大小還需要知道屏幕的dpi ,然后用象素除以dpi 就可以得到多少英寸了
//獲取電腦屏幕信息
public static void getScreen() { Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize(); int width = (int)screensize.getWidth(); int height = (int)screensize.getHeight(); System.out.println("寬的像素:"+width+"高的像素:"+height); //獲取屏幕的dpi int dpi = Toolkit.getDefaultToolkit().getScreenResolution(); System.out.println(dpi); //根據dpi和像素,可以計算物理尺寸 System.out.println("寬:"+width/dpi+"高:"+height/dpi); }
