爬蟲抓取分頁數據的簡單實現

昨天,咱們已經利用Jsoup技術實現了一個簡單的爬蟲,原理很簡單,主要是要先分析頁面,拿到條件,而後就去匹配url,採用dome解析的方式循環抓取咱們須要的數據,從而便可輕鬆實現一個簡單的爬蟲。那麼,昨天咱們說了,咱們昨天只是爬取了一頁的數據也就是第一頁的數據,若想獲取分頁的所有數據該怎麼寫呢?正好,今天朋友託我幫忙買一種藥,說是她那邊沒有,因而,我就查詢了一下佛山的各大藥店,利用咱們剛學的爬蟲技術,咱們今天就來實現一下愛幫網上佛山藥店的分佈列表。html

1、需求分析web

首先,咱們登錄愛幫網,選擇城區以及輸入關鍵字,咱們輸入的是「藥店」,點擊搜索按鈕,咱們打開控制檯,觀察頭信息,以下圖:dom

 

咱們經過觀察能夠看到請求的url地址以及參數;其實直接看地址欄就能夠看得出來,咱們點擊第二頁發現其餘參數都不變,只有參數p的值隨頁碼的變化而變化。那麼,這樣以來,咱們就能夠知道每一頁的請求地址其實都是同樣的,只要改變p的值便可,而後咱們看頁面總頁數只有8頁,數據量不大,寫個循環循環8次便可。下面咱們就來開始實現,依然在昨天的代碼的基礎上改一改便可。ide

 

2、開發測試

一、咱們首先須要改一下咱們的業務實現類,由於取值的方式已經不同了,以下圖:網站

咱們要去的class爲aside中的內容,一樣是拿到<a>標籤,可是咱們觀察得知頁面有不少的<a>標籤,咱們要取得咱們須要的,以下圖:url

/*
         * 提取結果中的連接地址和連接標題,返回數據
         */
        
        for(Element result : results){
            Elements links = result.getElementsByTag("a");//能夠拿到連接
            for(Element link : links){
                    if(link.siblingElements().hasClass("num")){
                        String id = link.siblingElements().text();
                        String linkText = link.text();
                        LinkTypeData data1 = new LinkTypeData();
                        if(id!=null && linkText!=null){
                            data1.setId(id);
                            data1.setLinkText(linkText);
                        }
                        datas.add(data1);
                    }
                    if(link.parent().parent().hasClass("part1")){
                        LinkTypeData data2 = new LinkTypeData();
                        String address = link.parent().siblingElements().text();
                        if(address!=null){
                            data2.setSummary(address);
                        }
                        datas.add(data2);
                    }
                    if(link.parent().siblingElements().tagName("span").hasClass("biztel")){
                        LinkTypeData data3 = new LinkTypeData();
                        String telnum = link.parent().siblingElements().tagName("span").text();
                        if(telnum!=null){
                            data3.setContent(telnum);
                        }
                        datas.add(data3);
                    }
                }
                    // 對取得的html中的&nbsp;出現問號亂碼進行處理
                    /*linkText = new String(linkText.getBytes(),"GBK").replace('?', ' ').replace(' ', ' ');
                    String id = link.parent().firstElementSibling().text();
                    id = new String(id.getBytes(),"GBK").replace('?', ' ').replace(' ', ' ');
                    String address = link.parent().nextElementSibling().text();
                    address = new String(address.getBytes(),"GBK").replace('?', ' ').replace(' ', ' ');
                    String code = link.parent().lastElementSibling().text();
                    code = new String(code.getBytes(),"GBK").replace('?', ' ').replace(' ', ' ');*/
                    
                    /*data.setSummary(address);
                    data.setContent(code);
                    data.setId(id);*/

        }
        return datas;
    }
    

 

咱們在昨天的代碼基礎上進行了更改。這樣就取得了咱們想要的數據。spa

3、測試code

接下來咱們就能夠改一下咱們的測試類,咱們須要循環8次,而每一次獲取到的數據咱們都存進一個新的集合中,而後最後再拿出新的集合的數據寫進Excel。htm

/**
     * 不帶查詢參數
     * @author AoXiang
     * 2017年3月21日
     */
    @org.junit.Test
    public void getDataByClass() throws IOException{
        List<LinkTypeData> newList = new ArrayList<LinkTypeData>();
        for(int i=1;i<=8;i++){
            Rule rule = new Rule( "http://www.aibang.com/?area=bizsearch2&cmd=bigmap&city=%E4%BD%9B%E5%B1%B1&a=%E5%8D%97%E6%B5%B7%E5%8C%BA&q=%E8%8D%AF%E5%BA%97&as=5000&ufcate=&rc=1&zone=&quan=&fm=&p="+i,
                    null,null,
                    "aside", Rule.CLASS, Rule.POST);
            List<LinkTypeData> datas = ExtractService.extract(rule);
            for(int j=0;j<datas.size();j++){
                newList.add(datas.get(j));
            }
        }
        // 第一步,建立一個webbook,對應一個Excel文件  
        HSSFWorkbook wb = new HSSFWorkbook();  
        // 第二步,在webbook中添加一個sheet,對應Excel文件中的sheet  
        HSSFSheet sheet = wb.createSheet("佛山藥店");  
        // 第三步,在sheet中添加表頭第0行,注意老版本poi對Excel的行數列數有限制short  
        HSSFRow row = sheet.createRow((int) 0);  
        // 第四步,建立單元格,並設置值表頭 設置表頭居中  
        HSSFCellStyle style = wb.createCellStyle();  
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 建立一個居中格式  
        HSSFCell cell = row.createCell((short) 0);  
        cell.setCellValue("序號");  
        cell.setCellStyle(style);  
        cell = row.createCell((short) 1);  
        cell.setCellValue("藥店名稱");  
        cell.setCellStyle(style);  
        cell = row.createCell((short) 2);  
        cell.setCellValue("地址");  
        cell.setCellStyle(style);  
        cell = row.createCell((short) 3);  
        cell.setCellValue("電話");  
        cell.setCellStyle(style);  
        for(int m=0;m<newList.size();m++){
            // 第五步,寫入實體數據
            row = sheet.createRow((int)m  + 1);  
            // 第四步,建立單元格,並設置值  
            row.createCell((short) 0).setCellValue(newList.get(m).getId());  
            row.createCell((short) 1).setCellValue(newList.get(m).getLinkText());  
            row.createCell((short) 2).setCellValue(newList.get(m).getSummary());  
            row.createCell((short) 3).setCellValue(newList.get(m).getContent());  
        }
          // 第六步,將文件存到指定位置  
        try  
        {  
            FileOutputStream fout = new FileOutputStream("F:/佛山藥店.xls");  
            wb.write(fout);  
            fout.close();  
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }  
    }

咱們運行一下看結果:

 好了,咱們已經拿到咱們須要的數據了,而後就能夠對這些數據進行分析,爲我麼所用。

其實,這只是一個簡單的網站,通常如今的網站有些分頁是JS動態獲取的,咱們看不到分頁信息,那麼,這就須要咱們靈活應變,爬蟲技術也不是隻有這一種,然而萬變不離其宗,掌握了要領和方法,相信不會有任何困難。

源碼就不用上傳了,有興趣的同窗能夠參考一下,其實就是改了兩處地方。

若是您對代碼有什麼異議歡迎您的留言,咱們一塊兒交流!

相關文章
相關標籤/搜索