盘点用Java抓取HTTP服务器和FTP服务器的网页数据或图片等数据的实用技巧

摘要

在信息时代,常常需要通过编程的方式来灵活整理各种网络数据。首先涉及到如何方便准确地抓取网络数据。下面盘点用Java程序来访问HTTP服务器以及FTP服务器的各种实用技巧。主要介绍了Java Socket、java.net.URL类、Selenuim软件包、Apache HttpClients、Apache FTPClient来和HTTP服务器以及FTP服务器通信的方法以及其优缺点。
参考资料

一、用Java Socket访问HTTP服务器

通过Socket访问HTTP服务器,需要了解具体的HTTP协议通信细节,由Socket获得输入流和输出流,然后通过输入流发送HTTP请求数据,通过输出流读取HTTP响应结果。程序得到了HTTP响应结果后,需要对响应头和响应正文进行解析。

这是最原始的方法,給程序员提供了很灵活地发挥空间,可以炮制各种各样的HTTP请求数据。缺点是处理HTTP响应结果比较麻烦。尤其是现在许多网站发回的数据会先进行gzip压缩。客户端得到了这样的数据后,还需要进行解压,才能得到真实的数据。

这种方法的使用技巧和范例请参考 用Java套接字访问HTTP服务器读取网页数据

二、用java.net.URL等类访问HTTP服务器

URL类以及其相关的URLConnection类称为客户端协议处理框架,它对原始的HTTP通信细节进行了封装。程序员只需要提供一个URL地址,就能发送HTTP请求数据以及读取HTTP响应结果。如果服务器端对HTML文档进行了gzip压缩,客户端协议处理框架会对HTML文档进行解压,再作为响应结果的正文返回給客户程序,这是比直接用Socket读取HTML文档更省力的地方。

以下getByteSource()方法能根据给定的URL地址,返回相应的响应结果的正文部分的字节流,以byte[]形式返回。

 public static byte[] getByteSource(String  urlStr)throws IOException{
     URL url=new URL(urlStr);

    HttpURLConnection.setFollowRedirects(true);   //设置允许重定向
    //此处创建URLConnection对象时,并不会进行真实地与HTTP服务器的连接,
    //只有当调用URLConnection的connect()方法,或者发送HTTP请求以及读取HTTP响应结果时才会连接服务器
    URLConnection connection=url.openConnection();
    connection.setConnectTimeout(60000); //设置连接超时时间为60秒
    connection.setReadTimeout(60000);  //设置读取数据超时时间为60秒

    //演示设置HTTP请求头部的信息
    connection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36");
    connection.setRequestProperty("Connection","keep-alive");
    connection.setRequestProperty("Content-Type","text/plain;charset=UTF-8");
    connection.setRequestProperty("X-Buffalo-Version","2.0-alpha3");
    connection.setRequestProperty("Sec-Fetch-Mode","cors");
    connection.setRequestProperty("Accept"," */*");
    connection.setRequestProperty("Sec-Fetch-Site","same-origin");
    connection.setRequestProperty("Accept-Encoding","deflate, br");
    connection.setRequestProperty("Accept-Language","zh-CN,zh;q=0.9");  

   //演示遍历访问响应结果的头部信息
   Map<String,List<String>> headers=connection.getHeaderFields();
   Set<String> keySet=headers.keySet();
   for(String key:keySet){
      //响应头中的每一项可能有多个取值,此处仅打印第一个取值
     System.out.println(key+":"+headers.get(key).get(0));
   }

   //读取响应头部的特定项的值
   String location=connection.getHeaderField("Location");

     //读取响应正文的数据
    InputStream in=connection.getInputStream();
    ByteArrayOutputStream buffer=new ByteArrayOutputStream();
    byte[] buff=new byte[1024];
    int len=-1;

    while((len=in.read(buff))!=-1){
      buffer.write(buff,0,len);
    }

    return buffer.toByteArray();
  }  

以下getStringSource()方法演示获得HTML文本数据。它利用上面的getByteSource()方法得到HTTP响应正文的字节流,再把它包装成一个字符串对象。需要指定响应正文的字符编码。

 public static String getStringSource(String urlStr,String encode)throws IOException{
     byte[] buffer=getByteSource(urlStr);
     String data=new String(buffer,tencode);
    return data;  //把字节数组转换为字符串
  }

客户端协议处理框架的更多使用技巧和范例请参考 用java.net.URL类访问HTTP服务器读取网页数据

三、用Selenium软件API访问HTTP服务器

Selenium是一个专业的爬虫软件。它支持Java和Python等语言。当通过上述java.net.URL类来读取网站的HTML文档时,有时候读到的仅仅是JavaScript脚本,而真正的HTML文档需要运行JavaScript才能获得。Selenium能够利用Chrome浏览器或者是FireFox浏览器的驱动程序来启动浏览器,由浏览器执行JavaScript脚本,然后返回真实的HTML文档。
Selenium具有以下优势:
(1)利用浏览器动态执行JavaScript脚本的功能,获得真正要访问的HTML文本数据。
(2)对HTML文档进行了DOM(文档对象模型)建模,可以方便地访问HTML文档中各个元素的属性。

关于用Selenium获取HTML文档的方法和范例请参考:Java版Selenium使用chrome driver抓取动态网页

Selenium读取和处理HTML文档比较方便,但是目前在抓取网页图片方面比较麻烦。一种做法是先把整个网页进行截屏,得到一个图片。然后截取特定元素在整个图片中所在的区域,获得元素所对应的图片。这种做法的缺点是: 如果对网页的截屏的大小取决于电脑屏幕的大小。对于需要通过滚动屏幕才能显示的网页部分内容,则不能一次性截屏。

对于不在截屏图片范围内的元素,如果试图截取这个元素对应区域的图片,程序会抛出Outside of Raster的异常。

关于用Selenium截取网页图片以及特定元素的图片的方法和范例请参考: Java版Selenium 截取网页上特定元素的图片的方法

如果用Selenium来抓图比较方法,还可以使用java.net.URL或者Apache HttpClients来抓图。关于把Selenium和java.net.URL类结合使用,来读取HTML文档以及下载文档中<img>元素指定图片的方法,请参考: 用Selenium 爬虫API和java.net.URL类保存网页上的图片

使用Selenium的另一个缺点是比较“笨重”,必须安装Chrome浏览器,下载对应的Chrome驱动器程序,提供Selenium的多个类库文件。

四、用Apache HttpClients下载网上的图片等各种数据

用java.net.URL来下载图片数据时,如果HTTP服务器端对图片数据进行了重定向,或者进行了特殊格式的压缩,有时还是无法获取正确的原始图片数据。在这种情况下,可以使用Apach HttpClients API。

关于用Apache HttpClients来下载各种网页数据的方法,请参考: 用Apache HttpClients下载网上的图片等各种数据

在实际应用中,可以利用Selenium来读取需要动态执行JavaScript脚本的网页,用Apache Clients来下载网页中的图片等数据,这样会解决抓取数据中遇到的各种障碍。

五、用Apache FTPClient访问FTP服务器

Java程序除了要访问HTTP服务器,还需要访问FTP服务器。Apache FTPClient API提供了访问FTP服务器的各种功能,包括:

  • 下载和上传文件
  • 浏览FTP服务器端的文件信息
  • 在远程FTP服务器上创建或删除文件以及目录

关于用Apache HttpClients来上传文件的方法,请参考: 用 Apache 的FTPClient上传文件
关于用Apache HttpClients在FTP服务器上创建目录的方法,请参考:用Apache FTPClient在FTP服务器上创建目录

作者:孙卫琴

原文地址:https://blog.51cto.com/sunweiqin/2465817

时间: 2024-10-08 21:12:21

盘点用Java抓取HTTP服务器和FTP服务器的网页数据或图片等数据的实用技巧的相关文章

Java抓取利用JS动态加载的网页

最近实验室项目涉及到很多爬虫相关的东西,在此做个整理,爬虫最难的问题应该是javascript和ajax的处理.现在很多网站使用大量ajax,普通爬虫无法获取js生成的内容. 对于普通的静态网页,HttpClient是Java中抓取网页的利器,然而针对像京东商品页面这样的页面却无能为力,例如:http://item.jd.com/10875285.html 主要原因是页面中的一部分信息比如商品评论是通过JavaScript异步加载的,如果直接通过HttpClient直接抓取只会得到其中的js代码

java抓取12306火车余票信息

最近在弄一个微信的公众帐号,涉及到火车票查询,之前用的网上找到的一个接口,但只能查到火车时刻表,12306又没有提供专门的查票的接口.今天突然想起自己直接去12306上查询,抓取查询返回的数据包,这样就可以得到火车票的信息.这里就随笔记一下获取12306余票的过程. 首先,我用firefox浏览器上12306查询余票.打开firefox的Web控制台,选上网络中的"记录请求和响应主体" 然后输入地址日期信息之后点击网页上的查询按钮,就能在Web控制台下看到网页请求的地址了: 就是图片中

java 抓取网页图片

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

java抓取网页数据,登录之后抓取数据。

最近做了一个从网络上抓取数据的一个小程序.主要关于信贷方面,收集的一些黑名单网站,从该网站上抓取到自己系统中. 也找了一些资料,觉得没有一个很好的,全面的例子.因此在这里做个笔记提醒自己. 首先需要一个jsoup的jar包,我用的1.6.0..下载地址为:http://pan.baidu.com/s/1mgqOuHa 1,获取网页内容(核心代码,技术有限没封装). 2,登录之后抓取网页数据(如何在请求中携带cookie). 3,获取网站的ajax请求方法(返回json). 以上这三点我就用一个类

jsoup实现java抓取网页内容。

Java 程序在解析 HTML 文档时,相信大家都接触过 htmlparser 这个开源项目,我曾经在 IBM DW 上发表过两篇关于 htmlparser 的文章,分别是:从 HTML 中攫取你所需的信息和 扩展 HTMLParser 对自定义标签的处理能力.但现在我已经不再使用 htmlparser 了,原因是 htmlparser 很少更新,但最重要的是有了 jsoup . jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址.HTML 文本内容.它提供了一套非

用 Java 抓取优酷、土豆等视频

1. [代码][JavaScript]代码  import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements; /*** 视频工具类* @author sunlightcs* 2011-4-6* http://hi.juziku.com/sunlightcs/*/public class VideoUtil {       

java抓取动态生成的网页

最近在做项目的时候有一个需求:从网页面抓取数据,要求是首先抓取整个网页的html源码(后期更新要使用到).刚开始一看这个简单,然后就稀里哗啦的敲起了代码(在这之前使用过Hadoop平台的分布式爬虫框架Nutch,使用起来是很方便,但是最后因为速度的原因放弃了,但生成的统计信息在后来的抓取中使用到了),很快holder.html和finance.html页面成功下载完成,然后解析完holder.html页面之后再解析finance.html,然后很沮丧的发现在这个页面中我需要的数据并没有在html

Java抓取网页数据(原网页+Javascript返回数据)

转载请注明出处! 原文链接:http://blog.csdn.net/zgyulongfei/article/details/7909006 有时候因为种种原因,我们须要採集某个站点的数据,但因为不同站点对数据的显示方式略有不同! 本文就用Java给大家演示怎样抓取站点的数据:(1)抓取原网页数据:(2)抓取网页Javascript返回的数据. 一.抓取原网页. 这个样例我们准备从http://ip.chinaz.com上抓取ip查询的结果: 第一步:打开这个网页,然后输入IP:111.142.

java抓取动态生成的网页--吐槽

最近在做项目的时候有一个需求:从网页面抓取数据,要求是首先抓取整个网页的html源码(后期更新要使用到).刚开始一看这个简单,然后就稀里哗啦的敲起了代码(在这之前使用过Hadoop平台的分布式爬虫框架Nutch,使用起来是很方便,但是最后因为速度的原因放弃了,但生成的统计信息在后来的抓取中使用到了),很快holder.html和finance.html页面成功下载完成,然后解析完holder.html页面之后再解析finance.html,然后很沮丧的发现在这个页面中我需要的数据并没有在html