zoukankan      html  css  js  c++  java
  • 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的库真特么变态

  • 相关阅读:
    结对编程之附加题:单元测试
    机器学习第二次作业
    第一次作业
    机器学习第二次作业
    机器学习第一次个人作业
    软工实践个人总结
    第08组 Beta版本演示
    第08组 Beta冲刺(5/5)
    第08组 Beta冲刺(4/5)
    第08组 Beta冲刺(3/5)
  • 原文地址:https://www.cnblogs.com/TTyb/p/5784581.html
Copyright © 2011-2022 走看看