日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

爬蟲(chóng)抓取分頁(yè)數(shù)據(jù)的簡(jiǎn)單實(shí)現(xiàn)

 Levy_X 2017-10-05

昨天,我們已經(jīng)利用Jsoup技術(shù)實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的爬蟲(chóng),原理很簡(jiǎn)單,主要是要先分析頁(yè)面,拿到條件,然后就去匹配url,采用dome解析的方式循環(huán)抓取我們需要的數(shù)據(jù),從而即可輕松實(shí)現(xiàn)一個(gè)簡(jiǎn)單的爬蟲(chóng)。那么,昨天我們說(shuō)了,我們昨天只是爬取了一頁(yè)的數(shù)據(jù)也就是第一頁(yè)的數(shù)據(jù),若想獲取分頁(yè)的全部數(shù)據(jù)該怎么寫(xiě)呢?正好,今天朋友托我?guī)兔I(mǎi)一種藥,說(shuō)是她那邊沒(méi)有,于是,我就查詢了一下佛山的各大藥店,利用我們剛學(xué)的爬蟲(chóng)技術(shù),我們今天就來(lái)實(shí)現(xiàn)一下愛(ài)幫網(wǎng)上佛山藥店的分布列表。

一、需求分析

首先,我們登陸愛(ài)幫網(wǎng),選擇城區(qū)以及輸入關(guān)鍵字,我們輸入的是“藥店”,點(diǎn)擊搜索按鈕,我們打開(kāi)控制臺(tái),觀察頭信息,如下圖:

 

我們通過(guò)觀察可以看到請(qǐng)求的url地址以及參數(shù);其實(shí)直接看地址欄就可以看得出來(lái),我們點(diǎn)擊第二頁(yè)發(fā)現(xiàn)其他參數(shù)都不變,只有參數(shù)p的值隨頁(yè)碼的變化而變化。那么,這樣以來(lái),我們就可以知道每一頁(yè)的請(qǐng)求地址其實(shí)都是一樣的,只要改變p的值即可,然后我們看頁(yè)面總頁(yè)數(shù)只有8頁(yè),數(shù)據(jù)量不大,寫(xiě)個(gè)循環(huán)循環(huán)8次即可。下面我們就來(lái)開(kāi)始實(shí)現(xiàn),依然在昨天的代碼的基礎(chǔ)上改一改即可。

 

二、開(kāi)發(fā)

1、我們首先需要改一下我們的業(yè)務(wù)實(shí)現(xiàn)類(lèi),因?yàn)槿≈档姆绞揭呀?jīng)不一樣了,如下圖:

我們要去的class為aside中的內(nèi)容,同樣是拿到<a>標(biāo)簽,但是我們觀察得知頁(yè)面有很多的<a>標(biāo)簽,我們要取得我們需要的,如下圖:

復(fù)制代碼
/*
         * 提取結(jié)果中的鏈接地址和鏈接標(biāo)題,返回?cái)?shù)據(jù)
         */
        
        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);
                    }
                }
                    // 對(duì)取得的html中的 出現(xiàn)問(wèn)號(hào)亂碼進(jìn)行處理
                    /*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;
    }
    
復(fù)制代碼

 

我們?cè)谧蛱斓拇a基礎(chǔ)上進(jìn)行了更改。這樣就取得了我們想要的數(shù)據(jù)。

三、測(cè)試

接下來(lái)我們就可以改一下我們的測(cè)試類(lèi),我們需要循環(huán)8次,而每一次獲取到的數(shù)據(jù)我們都存進(jìn)一個(gè)新的集合中,然后最后再拿出新的集合的數(shù)據(jù)寫(xiě)進(jìn)Excel。

復(fù)制代碼
/**
     * 不帶查詢參數(shù)
     * @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./?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));
            }
        }
        // 第一步,創(chuàng)建一個(gè)webbook,對(duì)應(yīng)一個(gè)Excel文件  
        HSSFWorkbook wb = new HSSFWorkbook();  
        // 第二步,在webbook中添加一個(gè)sheet,對(duì)應(yīng)Excel文件中的sheet  
        HSSFSheet sheet = wb.createSheet("佛山藥店");  
        // 第三步,在sheet中添加表頭第0行,注意老版本poi對(duì)Excel的行數(shù)列數(shù)有限制short  
        HSSFRow row = sheet.createRow((int) 0);  
        // 第四步,創(chuàng)建單元格,并設(shè)置值表頭 設(shè)置表頭居中  
        HSSFCellStyle style = wb.createCellStyle();  
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 創(chuàng)建一個(gè)居中格式  
        HSSFCell cell = row.createCell((short) 0);  
        cell.setCellValue("序號(hào)");  
        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++){
            // 第五步,寫(xiě)入實(shí)體數(shù)據(jù)
            row = sheet.createRow((int)m  + 1);  
            // 第四步,創(chuàng)建單元格,并設(shè)置值  
            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();  
        }  
    }
復(fù)制代碼

我們運(yùn)行一下看結(jié)果:

 好了,我們已經(jīng)拿到我們需要的數(shù)據(jù)了,然后就可以對(duì)這些數(shù)據(jù)進(jìn)行分析,為我么所用。

其實(shí),這只是一個(gè)簡(jiǎn)單的網(wǎng)站,一般現(xiàn)在的網(wǎng)站有些分頁(yè)是JS動(dòng)態(tài)獲取的,我們看不到分頁(yè)信息,那么,這就需要我們靈活應(yīng)變,爬蟲(chóng)技術(shù)也不是只有這一種,然而萬(wàn)變不離其宗,掌握了要領(lǐng)和方法,相信不會(huì)有任何困難。

源碼就不用上傳了,有興趣的同學(xué)可以參考一下,其實(shí)就是改了兩處地方。

如果您對(duì)代碼有什么異議歡迎您的留言,我們一起交流!

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多