初學java爬蟲【一】+獲取省份地區規劃信息

6月二十五號開始,CSDN首頁就一直在推送關於爬取網易雲音樂評論的的相關文章,但是,能力有限,對於做了反爬蟲處理的就弄不來了。最近在學網頁中的三級聯動,但是沒有找到關於省份、城市、縣區的數組,只能列出簡單的幾個示範,就意外看到了2017年統計用區劃代碼,查看源碼也是將包括了信息展示的,可以拿來練練手。開始呢,觀摩了一下這個結構,省份名前都是帶有簡短的html地址的,不過需要拼接;並且下一級再下一級也都是一樣的,所以我只需要寫一個方法就可以把所有的信息(省+市區+縣區)都給讀取出來。

爲了讓自己能夠有個可視化的操作,用類似節點的方式,自己看的更加明白些,就多寫了個創建文件夾的方法。


效果就是和上面這樣。當然這個可以擴展,起初只是可視化一下,下一篇寫JDBC的,將信息保存到數據庫。

具體的實現需要jsoup包,用於解析html的代碼類庫。

我們需要藉助包的幾個方法

第一:(注意:別導錯了包)

第二:就OK了。html()的返回類型就是一個String類型。他會把所有的源碼變成一個帶格式的字符串輸出

(注意:別導錯了包)


以下就是簡單的爬去網頁源碼。


至於userAgent().get()的特殊請求可以參照大牛的博客

我寫的是將其拆分成一個數組,並用正則表達式中的分組獲取到我需要的數據,省的信息暫時保存在home.txt文件當中,而創建文件夾就是讀取其中的數據,並根據其中拼接的網址,繼續傳入方法。照此循環。創建了有336個文件。我的電腦運行看七八分鐘吧。至於沒有再繼續往縣級別創建文件夾是怕電腦會燒壞。吐舌頭

import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BootMain {
    /**
     *     創建Pattern對象,放入正則表達式
     */
    static Pattern p=Pattern.compile("(\\d+\\.html)\">([\\u4e00-\\u9fa5]{2,8}[市省區縣鄉鎮會鄉])");
    static Pattern pFileName=Pattern.compile("[\\u4e00-\\u9fa5]{2,8}[市省區縣鄉鎮會鄉]");

    static BufferedReader bw=null;
    static  RobotAddress robotAddress=new RobotAddress();
    static  String indexURL="http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2017/";
    BootMain m=new BootMain();
    public static void main(String[] args) {
    File file=new File("Address");
    if (!file.exists()){
        file.mkdir();
    }
    /**
        第一步獲取所有的省份地址,並創建省級文件夾
     */
        String homeFilePath="Address\\home.txt";
        //首先獲取主頁的數據加上主頁的後綴
        robotAddress.home(indexURL+"index.html",homeFilePath,1);
        //調用創建文件夾創建,創建各城市的文件夾
        robotAddress.newFolder(homeFilePath,"Address\\");
        System.out.println("省級文件夾創建成功!開始創建市級城市文件夾");
        /**
         * 第二步
         * 需要循環讀取home中的網址信息,傳入到兩個方法中
         * 我在這邊需要循環讀取home的城市信息,輸出到方法當中
         */

        BufferedReader br=null;
        try {
            //讀取的文件
            br=new BufferedReader(new FileReader(homeFilePath));
            String shear="";
            while ((shear=br.readLine())!=null){
                String name=shear.substring(shear.lastIndexOf("#")+1);
                String url=shear.substring(0,shear.lastIndexOf("#"));
                String saveFilePath="Address\\"+name+"\\"+name+".txt";
                    //固定網址+各省份的地址----各省份的名字
                robotAddress.home(url,saveFilePath,2);
                }
            br.close();
            System.out.println("市級城市文件夾創建成功!開始創建區縣文件夾");
            /**
             * 第三步 獲取每個子文件中的信息-再創建市/區的文件夾
             * 再通過home.txt文件信息,拿到省的名字,拿到其根目錄下的xx省.txt文件,傳入newFolder方法,
             */
            String[] provinceNameLists=file.list();
            //輸出其目錄下的文件列表
            for (int i = 0; i <provinceNameLists.length ; i++) {
                //判斷是否爲文件夾    獲取文件夾中子文本信息
                //folder--Address\\江西\\
                String folder="Address\\"+provinceNameLists[i]+"\\";
                //provinceInfoPath--Address\\江西\\江西省.txt
                String provinceInfoPath=folder+provinceNameLists[i]+".txt";
                //傳入到出創建文件夾方法中
                if (provinceNameLists[i].indexOf(".")==-1){
                    robotAddress.newFolder(provinceInfoPath,folder);
                    /**
                     * 第四步 獲取每個子文件中的信息,傳入home方法。
                     */
                    File cityFile =new File(folder+"\\");
                    //將個省份的城市名稱放入數組
                    String[] cityNameLists=cityFile.list();
                    //傳入創建文件夾方法
                    for (int j = 0; j <cityNameLists.length ; j++) {
                        if (cityNameLists[j].indexOf(".")==-1){
                            //cityNamePath--Address\\江西省\\上饒市\\
                            String cityNamePath=folder+"\\"+cityNameLists[j];
                            //讀取寫入的城市信息
                            br=new BufferedReader(new FileReader(provinceInfoPath));
                            while ((shear=br.readLine())!=null){
                                String name=shear.substring(shear.lastIndexOf("#")+1);
                                String url=shear.substring(0,shear.lastIndexOf("#"));
                                //保存 市級城市信息文件的地址---Address\\江西省\\上饒市\\上饒市.txt
                                String saveFilePath=cityNamePath+"\\"+cityNameLists[j]+".txt";
                                //固定網址+各省份的地址----各省份的名字
                                robotAddress.home(url,saveFilePath,2);
                                //創建文件夾--各市中的縣級文件夾
                                 robotAddress.newFolder(saveFilePath,cityNamePath+"\\"+name+"\\");
                            }
                            br.close();
                        }

                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;

public class RobotAddress {
    /**
     *保存html地址到本地
     * @param URL 爬取的地址
     * @param saveFilePath 關鍵字信息保存的地址
     * @param order 程序運行的步驟
     */
    public void home(String URL,String saveFilePath,int order){
        BufferedWriter bw=null;
        //暫時儲存爲HTMl源碼的路徑
        String deleteUrl="Address\\test.txt";
        try {
            Document document=Jsoup.connect(URL).userAgent("").get();
            String[] htmls=document.html().split("\n");
            //創建新的文件對象,寫入
            bw=new BufferedWriter(new FileWriter(saveFilePath));
            for (int i = 0; i <htmls.length ; i++) {
                Matcher m= BootMain.p.matcher(htmls[i]);
                //符合我要爬的內容,寫入文檔
                if (m.find()){
                    switch (order){
                        case 1:
                             /*
                                 第一步-寫入每個省份的信息到home.txt
                              */
                            bw.write(BootMain.indexURL+m.group(1)+"#"+m.group(2));
                            break;
                        case 2:
                              /*
                               第二步-寫入對應省份的子文件夾
                              */
                            bw.write(URL.substring(0,URL.lastIndexOf("."))+"/"+m.group(1)+"#"+m.group(2));
                            break;
                        default:
                            break;
                    }

                    bw.newLine();
                }
            }
            //關閉流
            bw.close();
            System.out.println("^_^寫入成功");
        } catch (Exception e) {
            //捕捉異常-保證繼續運行
            Date d=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                bw=new BufferedWriter(new FileWriter("Address\\Exception.txt",true));
                //寫入錯誤情況下的  地址-錯誤信息-時間
                bw.write(URL+"\t"+e.toString()+"\t"+sdf.format(d));
                bw.newLine();
                System.out.println(e);
            } catch (IOException e1) {
                System.out.println(e1);
            }
        }finally {
            //關閉資源
            if (bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
    /**
     * 讀取主頁txt獲取其中的  城市的URL並創建相應的文件
     * 需要傳入地址
     * @param infoPath 1.讀取城市信息的路徑(本地)(動態變化的)
     * @param folder 2.創建文件夾的父級文件夾(動態變化)
     */
    public void newFolder(String infoPath,String folder) {
        try {
            File file = null;
            //讀取的文件
            BufferedReader br = new BufferedReader(new FileReader(infoPath));
            String shear = null;
            while ((shear = br.readLine()) != null) {
                String name = shear.substring(shear.indexOf("#") + 1);
                //將讀取到的地址名拿出來放File路徑當中,文件名爲截取出來的對象
                file = new File(folder+ name);
                //創建文件目錄
                file.mkdir();
            }
            br.close();
        } catch (Exception e) {
            //捕捉異常-保證繼續運行
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter("Address\\Exception.txt", true));
                //寫入錯誤情況下的  地址-錯誤信息-時間
                bw.write(infoPath + "\t" + e.toString() + "\t" + sdf.format(d));
                bw.newLine();
                System.out.println(e);
            } catch (IOException e1) {
                System.out.println(e1);
            }
        }
    }
}寫的
比較亂吧。歡迎交流。下載地址。其中刪除了部分城市文件夾。在後期文章會寫入數據庫、展示在html。

獲取中國33省份源碼。jdk1.8

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章