主要思路:
1、找到列表頁。
2、找到文章頁。
3、用一個隊列來保存將要爬取的網頁,爬取隊頭的url,如果隊列非空,則一直爬取。
4、如果是列表頁,則抽取里面所有的文章url進隊;如果是文章頁,則直接爬取至本地。
一個博客是起始頁url是這樣的:
http://www.cnblogs.com/joyeecheung/
第n頁是這樣的:
http://www.cnblogs.com/joyeecheung/default.html?page=n
文章的url是這樣的:
http://www.cnblogs.com/joyeecheung/p/[0-9]+.html
代碼如下:
public class boke { private Queue<String> data = new LinkedList<String>(); //文章頁面 String PAGE = "http://www.cnblogs.com/joyeecheung/p/[0-9]+.html"; Pattern p = Pattern.compile(PAGE); public void action(String target) throws IOException{ Matcher m = p.matcher(target); //如果是文章頁面則讀取 if(m.find()){ URL url = new URL(target); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.connect(); InputStream in = conn.getInputStream(); byte[] buf = new byte [1024]; int len = 0; //分割url,把文章的編號作為文件的名字 String [] bufen = target.split("/"); String name = bufen[bufen.length-1]; name = name.replaceAll("html", "txt"); File file = new File(name); FileOutputStream fp = new FileOutputStream(file); while((len=in.read(buf))!=-1){ fp.write(buf, 0, len); } fp.close(); } //如果是列表頁面 //抽取里面的文章頁面連接 else{ URL url = new URL(target); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.connect(); InputStream in = conn.getInputStream(); byte [] buf = new byte[1024]; //把列表頁的內容放到ByteArrayOutputStream中 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); int len = 0; while((len=in.read(buf))!=-1){ //System.out.println(len); outStream.write(buf,0,len); } in.close(); outStream.close(); String content = new String(outStream.toByteArray()); Matcher page = p.matcher(content); //抽取文章的url while(page.find()){ //將抽取的文章url進隊 data.add(page.group()); } } } public static void main(String args[]) throws IOException{ boke test = new boke(); //起始頁面 String start = "http://www.cnblogs.com/joyeecheung/"; test.data.add(start); //列表頁面 String page = "http://www.cnblogs.com/joyeecheung/default.html?page="; //總頁數 int total =15; //將15頁列表頁進隊 for(int i=2;i<=total;i++) test.data.add(page+i); //隊列非空則一直爬取 while(!test.data.isEmpty()) test.action(test.data.poll()); } }
提取到的文章url效果:
爬取后效果:
文章內容效果:
博客里面右邊會有推薦的文章欄,還有閱讀排行里面的文章,這里的文章url會對我們后面提取到的url造成重復,怎么辦呢?
我直接將文章編號作為文件名,如果重復的話,后一個會覆蓋前面的內容。
直接用隊列存儲url,用循環來爬取內容,效率一般。高效率的爬蟲支持多線程爬取,在此就不展開了。
這次對我關注的Joyee的文章進行了爬取,只是用作測試程序效果,沒有惡意,如有冒犯,請聯系刪除,謝謝。