昨天,我們已經利用Jsoup技術實現了一個簡單的爬蟲,原理很簡單,主要是要先分析頁面,拿到條件,然后就去匹配url,采用dome解析的方式循環抓取我們需要的數據,從而即可輕松實現一個簡單的爬蟲。那么,昨天我們說了,我們昨天只是爬取了一頁的數據也就是第一頁的數據,若想獲取分頁的全部數據該怎么寫呢?正好,今天朋友托我幫忙買一種葯,說是她那邊沒有,於是,我就查詢了一下佛山的各大葯店,利用我們剛學的爬蟲技術,我們今天就來實現一下愛幫網上佛山葯店的分布列表。
一、需求分析
首先,我們登陸愛幫網,選擇城區以及輸入關鍵字,我們輸入的是“葯店”,點擊搜索按鈕,我們打開控制台,觀察頭信息,如下圖:
我們通過觀察可以看到請求的url地址以及參數;其實直接看地址欄就可以看得出來,我們點擊第二頁發現其他參數都不變,只有參數p的值隨頁碼的變化而變化。那么,這樣以來,我們就可以知道每一頁的請求地址其實都是一樣的,只要改變p的值即可,然后我們看頁面總頁數只有8頁,數據量不大,寫個循環循環8次即可。下面我們就來開始實現,依然在昨天的代碼的基礎上改一改即可。
二、開發
1、我們首先需要改一下我們的業務實現類,因為取值的方式已經不一樣了,如下圖:
我們要去的class為aside中的內容,同樣是拿到<a>標簽,但是我們觀察得知頁面有很多的<a>標簽,我們要取得我們需要的,如下圖:
/* * 提取結果中的鏈接地址和鏈接標題,返回數據 */ 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中的 出現問號亂碼進行處理 /*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; }
我們在昨天的代碼基礎上進行了更改。這樣就取得了我們想要的數據。
三、測試
接下來我們就可以改一下我們的測試類,我們需要循環8次,而每一次獲取到的數據我們都存進一個新的集合中,然后最后再拿出新的集合的數據寫進Excel。
/** * 不帶查詢參數 * @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動態獲取的,我們看不到分頁信息,那么,這就需要我們靈活應變,爬蟲技術也不是只有這一種,然而萬變不離其宗,掌握了要領和方法,相信不會有任何困難。
源碼就不用上傳了,有興趣的同學可以參考一下,其實就是改了兩處地方。
如果您對代碼有什么異議歡迎您的留言,我們一起交流!