java从零到变身爬虫大神(一)
学习java3天有余,知道一些基本语法后
学习java爬虫,1天后开始出现明显效果
刚开始先从最简单的爬虫逻辑入手
爬虫最简单的解析面真的是这样
1 import org.jsoup.Jsoup; 2 import org.jsoup.nodes.Document; 3 import java.io.IOException; 4 5 public class Test { 6 public static void Get_Url(String url) { 7 try { 8 Document doc = Jsoup.connect(url) 9 //.data("query", "Java") 10 //.userAgent("头部") 11 //.cookie("auth", "token") 12 //.timeout(3000) 13 //.post() 14 .get(); 15 } catch (IOException e) { 16 e.printStackTrace(); 17 } 18 } 19 }
这只是一个函数而已
那么在下面加上:
1 //main函数 2 public static void main(String[] args) { 3 String url = "..."; 4 Get_Url(url); 5 }
哈哈,搞定
就是这么一个爬虫了
太神奇
但是得到的只是网页的html页面的东西
而且还没筛选
那么就筛选吧
1 public static void Get_Url(String url) { 2 try { 3 Document doc = Jsoup.connect(url) 4 //.data("query", "Java") 5 //.userAgent("头部") 6 //.cookie("auth", "token") 7 //.timeout(3000) 8 //.post() 9 .get(); 10 11 //得到html的所有东西 12 Element content = doc.getElementById("content"); 13 //分离出html下<a>...</a>之间的所有东西 14 Elements links = content.getElementsByTag("a"); 15 //Elements links = doc.select("a[href]"); 16 // 扩展名为.png的图片 17 Elements pngs = doc.select("img[src$=.png]"); 18 // class等于masthead的div标签 19 Element masthead = doc.select("div.masthead").first(); 20 21 for (Element link : links) { 22 //得到<a>...</a>里面的网址 23 String linkHref = link.attr("href"); 24 //得到<a>...</a>里面的汉字 25 String linkText = link.text(); 26 System.out.println(linkText); 27 } 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 }
那就用上面的来解析一下我的博客园
解析的是<a>...</a>之间的东西
看起来很不错,就是不错
-------------------------------我是快乐的分割线-------------------------------
其实还有另外一种爬虫的方法更加好
他能批量爬取网页保存到本地
先保存在本地再去正则什么的筛选自己想要的东西
这样效率比上面的那个高了很多
很多
很多
看代码!
1 //将抓取的网页变成html文件,保存在本地 2 public static void Save_Html(String url) { 3 try { 4 File dest = new File("src/temp_html/" + "保存的html的名字.html"); 5 //接收字节输入流 6 InputStream is; 7 //字节输出流 8 FileOutputStream fos = new FileOutputStream(dest); 9 10 URL temp = new URL(url); 11 is = temp.openStream(); 12 13 //为字节输入流加缓冲 14 BufferedInputStream bis = new BufferedInputStream(is); 15 //为字节输出流加缓冲 16 BufferedOutputStream bos = new BufferedOutputStream(fos); 17 18 int length; 19 20 byte[] bytes = new byte[1024*20]; 21 while((length = bis.read(bytes, 0, bytes.length)) != -1){ 22 fos.write(bytes, 0, length); 23 } 24 25 bos.close(); 26 fos.close(); 27 bis.close(); 28 is.close(); 29 } catch (IOException e) { 30 e.printStackTrace(); 31 } 32 }
这个方法直接将html保存在了文件夹src/temp_html/里面
在批量抓取网页的时候
都是先抓下来,保存为html或者json
然后在正则什么的进数据库
东西在本地了,自己想怎么搞就怎么搞
反爬虫关我什么事
上面两个方法都会造成一个问题
这个错误代表
这种爬虫方法太low逼
大部分网页都禁止了
所以,要加个头
就是UA
方法一那里的头部那里直接
1 .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
方法二间接加:
1 URL temp = new URL(url); 2 URLConnection uc = temp.openConnection(); 3 uc.addRequestProperty("User-Agent", "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"); 4 is = temp.openStream();
加了头部,几乎可以应付大部分网址了
-------------------------------我是快乐的分割线-------------------------------
将html下载到本地后需要解析啊
解析啊看这里啊
1 //解析本地的html 2 public static void Get_Localhtml(String path) { 3 4 //读取本地html的路径 5 File file = new File(path); 6 //生成一个数组用来存储这些路径下的文件名 7 File[] array = file.listFiles(); 8 //写个循环读取这些文件的名字 9 10 for(int i=0;i<array.length;i++){ 11 try{ 12 if(array[i].isFile()){ 13 //文件名字 14 System.out.println("正在解析网址:" + array[i].getName()); 15 16 //下面开始解析本地的html 17 Document doc = Jsoup.parse(array[i], "UTF-8"); 18 //得到html的所有东西 19 Element content = doc.getElementById("content"); 20 //分离出html下<a>...</a>之间的所有东西 21 Elements links = content.getElementsByTag("a"); 22 //Elements links = doc.select("a[href]"); 23 // 扩展名为.png的图片 24 Elements pngs = doc.select("img[src$=.png]"); 25 // class等于masthead的div标签 26 Element masthead = doc.select("div.masthead").first(); 27 28 for (Element link : links) { 29 //得到<a>...</a>里面的网址 30 String linkHref = link.attr("href"); 31 //得到<a>...</a>里面的汉字 32 String linkText = link.text(); 33 System.out.println(linkText); 34 } 35 } 36 }catch (Exception e) { 37 System.out.println("网址:" + array[i].getName() + "解析出错"); 38 e.printStackTrace(); 39 continue; 40 } 41 } 42 }
文字配的很漂亮
就这样解析出来啦
主函数加上
1 //main函数 2 public static void main(String[] args) { 3 String url = "http://www.cnblogs.com/TTyb/"; 4 String path = "src/temp_html/"; 5 Get_Localhtml(path); 6 }
那么这个文件夹里面的所有的html都要被我解析掉
好啦
3天java1天爬虫的结果就是这样子咯
-------------------------------我是快乐的分割线-------------------------------
其实对于这两种爬取html的方法来说,最好结合在一起
作者测试过
方法二稳定性不足
方法一速度不好
所以自己改正
将方法一放到方法二的catch里面去
当方法二出现错误的时候就会用到方法一
但是当方法一也错误的时候就跳过吧
结合如下:
1 import org.jsoup.Jsoup; 2 import org.jsoup.nodes.Document; 3 import org.jsoup.nodes.Element; 4 import org.jsoup.select.Elements; 5 6 import java.io.BufferedInputStream; 7 import java.io.BufferedOutputStream; 8 import java.io.BufferedReader; 9 import java.io.File; 10 import java.io.FileOutputStream; 11 import java.io.IOException; 12 import java.io.InputStream; 13 import java.io.InputStreamReader; 14 import java.io.OutputStream; 15 import java.io.OutputStreamWriter; 16 import java.net.HttpURLConnection; 17 import java.net.URL; 18 import java.net.URLConnection; 19 import java.util.Date; 20 import java.text.SimpleDateFormat; 21 22 public class JavaSpider { 23 24 //将抓取的网页变成html文件,保存在本地 25 public static void Save_Html(String url) { 26 try { 27 File dest = new File("src/temp_html/" + "我是名字.html"); 28 //接收字节输入流 29 InputStream is; 30 //字节输出流 31 FileOutputStream fos = new FileOutputStream(dest); 32 33 URL temp = new URL(url); 34 URLConnection uc = temp.openConnection(); 35 uc.addRequestProperty("User-Agent", "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"); 36 is = temp.openStream(); 37 38 //为字节输入流加缓冲 39 BufferedInputStream bis = new BufferedInputStream(is); 40 //为字节输出流加缓冲 41 BufferedOutputStream bos = new BufferedOutputStream(fos); 42 43 int length; 44 45 byte[] bytes = new byte[1024*20]; 46 while((length = bis.read(bytes, 0, bytes.length)) != -1){ 47 fos.write(bytes, 0, length); 48 } 49 50 bos.close(); 51 fos.close(); 52 bis.close(); 53 is.close(); 54 } catch (IOException e) { 55 e.printStackTrace(); 56 System.out.println("openStream流错误,跳转get流"); 57 //如果上面的那种方法解析错误 58 //那么就用下面这一种方法解析 59 try{ 60 Document doc = Jsoup.connect(url) 61 .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)") 62 .timeout(3000) 63 .get(); 64 65 File dest = new File("src/temp_html/" + "我是名字.html"); 66 if(!dest.exists()) 67 dest.createNewFile(); 68 FileOutputStream out=new FileOutputStream(dest,false); 69 out.write(doc.toString().getBytes("utf-8")); 70 out.close(); 71 72 }catch (IOException E) { 73 E.printStackTrace(); 74 System.out.println("get流错误,请检查网址是否正确"); 75 } 76 77 } 78 } 79 80 //解析本地的html 81 public static void Get_Localhtml(String path) { 82 83 //读取本地html的路径 84 File file = new File(path); 85 //生成一个数组用来存储这些路径下的文件名 86 File[] array = file.listFiles(); 87 //写个循环读取这些文件的名字 88 89 for(int i=0;i<array.length;i++){ 90 try{ 91 if(array[i].isFile()){ 92 //文件名字 93 System.out.println("正在解析网址:" + array[i].getName()); 94 //文件地址加文件名字 95 //System.out.println("#####" + array[i]); 96 //一样的文件地址加文件名字 97 //System.out.println("*****" + array[i].getPath()); 98 99 100 //下面开始解析本地的html 101 Document doc = Jsoup.parse(array[i], "UTF-8"); 102 //得到html的所有东西 103 Element content = doc.getElementById("content"); 104 //分离出html下<a>...</a>之间的所有东西 105 Elements links = content.getElementsByTag("a"); 106 //Elements links = doc.select("a[href]"); 107 // 扩展名为.png的图片 108 Elements pngs = doc.select("img[src$=.png]"); 109 // class等于masthead的div标签 110 Element masthead = doc.select("div.masthead").first(); 111 112 for (Element link : links) { 113 //得到<a>...</a>里面的网址 114 String linkHref = link.attr("href"); 115 //得到<a>...</a>里面的汉字 116 String linkText = link.text(); 117 System.out.println(linkText); 118 } 119 } 120 }catch (Exception e) { 121 System.out.println("网址:" + array[i].getName() + "解析出错"); 122 e.printStackTrace(); 123 continue; 124 } 125 } 126 } 127 //main函数 128 public static void main(String[] args) { 129 String url = "http://www.cnblogs.com/TTyb/"; 130 String path = "src/temp_html/"; 131 //保存到本地的网页地址 132 Save_Html(url); 133 //解析本地的网页地址 134 Get_Localhtml(path); 135 } 136 }
总的来说
java爬虫的方法比python的多好多
java的库真特么变态