使用HttpClient和Jsoup实现一个简单爬虫
一直很想了解一下爬虫这个东西的,完全是出于兴趣,其实刚开始是准备用python的,但是由于种种原因选择了java,此处省略很多字... 总之,如果你想做一件事情的话就尽快去做吧,千万不要把战线拉得太长了,否则时间一长其实发现自己什么都没做... 拖延症就是这样慢慢形成了。
在写一个爬虫以前需要了解一下HTTP协议的,通常的B/S程序都是客户端请求、服务端响应这种模式,通过一个URL就能从服务器上请求到一些信息。而爬虫就是用程序实现了这个过程,用程序发起一个HTTP请求,然后接收服务端的响应结果,然后就从这些响应中抽取出你想要的信息。这里介绍了使用HttpClient和Jsoup编写的一个网络爬虫,爬取了http://jandan.net/上的一些图片,并且把图片保存到本地。
HttpClient
官网地址:http://hc.apache.org/httpclient-3.x/ 这是apache上的一个项目,主要作用是发起一个Http请求,并且接收响应,并且可以设置超时时间,比传统Java中的API要方便很多。
Jsoup
官网地址:https://jsoup.org/ 虽然这是官方地址,但是却是英文的,推荐看这里http://www.open-open.com/jsoup/这里是中文的文档,看这里就足够使用这个工具了,主要用于解析响应的html,但是也可以使用Jsoup发起一个http请求,但是功能没有HttpClient强大。所有一般是用HttpClient请求,Jsoup解析。
包含的jar包:
jsoup-1.7.2.jar
commons-logging-1.1.3.jar
httpclient-4.5.3.jar
httpcore-4.4.6.jar
直接上代码吧:这基本上是一个通用的类了,给定一个URL返回一个请求响应的html,并且设置了请求超时的参数。
package spider.img.service; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils; /**
* 2017-5-17 基础类,通过URL返回一个响应的html
*
* @author tom
*/
public class AbstractSpider { public static String getResult(String url) throws Exception {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse response = httpClient.execute(new HttpGetConfig(url))) {
String result = EntityUtils.toString(response.getEntity());
return result;
} catch (Exception e) {
System.out.println("获取失败");
return "";
}
}
} /**
* 内部类,继承HttpGet,为了设置请求超时的参数
*
* @author tom
*
*/
class HttpGetConfig extends HttpGet {
public HttpGetConfig(String url) {
super(url);
setDefaulConfig();
} private void setDefaulConfig() {
this.setConfig(RequestConfig.custom()
.setConnectionRequestTimeout(10000)
.setConnectTimeout(10000)
.setSocketTimeout(10000).build());
this.setHeader("User-Agent", "spider");
}
}
这里用了try-with-resource语法,是Java7的新特性,在try()括号中的资源会在try语句块执行完之后自动释放,所以不需要再finally中释放资源。
爬取图片的类:通过上面类的静态方法返回的结果,获取到返回的响应结果,然后通过jsoup解析。
package spider.img.service; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; /**
* 2017-5-17 爬取指定URL的图片
*
* @author tom
*
*/
public class SpiderImgs {
public SpiderImgs(String url) throws Exception {
//获取工具类返回的html,并用Jsoup解析
String result = AbstractSpider.getResult(url);
Document document = Jsoup.parse(result);
document.setBaseUri(url);
//获取所有的img元素
Elements elements = document.select("img");
for (Element e : elements) {
//获取每个src的绝对路径
String src = e.absUrl("src");
URL urlSource = new URL(src);
URLConnection urlConnection = urlSource.openConnection();
String imageName = src.substring(src.lastIndexOf("/") + 1, src.length());
System.out.println(e.absUrl("src"));
//通过URLConnection得到一个流,将图片写到流中,并且新建文件保存
InputStream in = urlConnection.getInputStream();
OutputStream out = new FileOutputStream(new File("E:\\IDEA\\imgs\\", imageName));
byte[] buf = new byte[1024];
int l = 0;
while ((l = in.read(buf)) != -1) {
out.write(buf, 0, l);
}
}
}
}
写一个单元测试试一下:
package spider.img.service.test; import org.junit.Test;
import spider.img.service.SpiderImgs; /**
* 2017-5-17 单元测试
* @author tom
*/
public class TestCase {
@Test
public void testGetResult() throws Exception{
SpiderImgs spider=new SpiderImgs("http://jandan.net/ooxx/page-60#comments");
}
}
控制台输出了一些东西,本地也保存了图片。
http://wx4.sinaimg.cn/mw600/0063qhYBgy1ffolz6oon2j30rs15o428.jpg
http://wx2.sinaimg.cn/mw600/0063qhYBgy1ffoiucdw5yj30xc0m9gpt.jpg
http://wx2.sinaimg.cn/mw600/0063qhYBgy1ffoivfcfpwj30xc0m9jt3.jpg
http://wx3.sinaimg.cn/mw600/0063qhYBgy1ffoiqgqqc0j30lc0w1402.jpg
http://wx3.sinaimg.cn/mw600/0063qhYBgy1ffoiqg5kz2j30hs0qogo7.jpg
http://wx4.sinaimg.cn/mw600/0063qhYBgy1ffoiqewsbej30go0l60wc.jpg
http://wx3.sinaimg.cn/mw600/0063qhYBgy1ffoiqdglc7j30lc0voq5k.jpg
http://wx4.sinaimg.cn/mw600/0063qhYBgy1ffoiqaz4dej30lc0w0gn6.jpg
github地址:https://github.com/silentyao/JavaImgSpider
使用HttpClient和Jsoup实现一个简单爬虫的更多相关文章
- [Java]使用HttpClient实现一个简单爬虫,抓取煎蛋妹子图
第一篇文章,就从一个简单爬虫开始吧. 这只虫子的功能很简单,抓取到”煎蛋网xxoo”网页(http://jandan.net/ooxx/page-1537),解析出其中的妹子图,保存至本地. 先放结果 ...
- C#写一个简单爬虫
最近研究C#的爬虫写法,搞了半天,才在网上很多的写法中整理出了一个简单的demo(本人菜鸟,大神勿喷).一是为了自己记录一下以免日后用到,二是为了供需要朋友参考. 废话不多说,上代码 using Ht ...
- 用node.js写一个简单爬虫,并将数据导出为 excel 文件
引子 最近折腾node,最开始像无头苍蝇一样到处找资料,然而多数没什么卵用,都在瞎比比.在一阵瞎搞后,我来分享一下初步学习node的三个过程: 1 撸一遍NODE入门,对其有个基本的了解: 2 撸一遍 ...
- [python]做一个简单爬虫
为什么选择python,它强大的库可以让你专注在爬虫这一件事上而不是更底层的更繁杂的事 爬虫说简单很简单,说麻烦也很麻烦,完全取决于你的需求是什么以及你爬的网站所决定的,遇到的第一个简单的例子是pas ...
- 爬虫浅谈一:一个简单c#爬虫程序
这篇文章只是简单展示一个基于HTTP请求如何抓取数据的文章,如觉得简单的朋友,后续我们再慢慢深入研究探讨. 图1: 如图1,我们工作过程中,无论平台网站还是企业官网,总少不了新闻展示.如某天产品经理跟 ...
- python多线程简单爬虫
爬虫本质就是将网站或者接口的数据经过筛选后按需求保存 这里实现一个简单爬虫仅供参考 import requests import bs4 import threading import queue i ...
- python 简单爬虫(beatifulsoup)
---恢复内容开始--- python爬虫学习从0开始 第一次学习了python语法,迫不及待的来开始python的项目.首先接触了爬虫,是一个简单爬虫.个人感觉python非常简洁,相比起java或 ...
- Stage6--Python简单爬虫
正则表达式简单介绍 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串.将匹配的子串做替换或者从某个串中取出符合某个条件的子串等. 字符 ...
- 【Java】Jsoup爬虫,一个简单获取京东商品信息的小Demo
简单记录 - Jsoup爬虫入门实战 数据问题?数据库获取,消息队列中获取中,都可以成为数据源,爬虫! 爬取数据:(获取请求返回的页面信息,筛选出我们想要的数据就可以了!) 我们经常需要分析HTML网 ...
随机推荐
- linq使用Take和Skip实现分页
;//第1页 ;//页大小 var list = list.Skip((pageIndex-1) * pageSize).Take(pageSize).ToList();
- js之返回网页顶部
目标效果:浏览网页过程中,滑动滚轮,显示返回顶部按钮,点击返回顶部后,返回网页顶端. 代码如下: <!DOCTYPE html> <html lang="en"& ...
- 在vue中赋值的路径没有被编译
当我们跑起来的时候,f12会看到相对路径,但是此时会报错,说找不到图片,这时候有其中一个办法,直接 require进去. 这时候就可以成功显示图片,但是路径会不一样,因为编译出来. 至于如何props ...
- Spark jdbc postgresql数据库连接和写入操作源码解读
概述:Spark postgresql jdbc 数据库连接和写入操作源码解读,详细记录了SparkSQL对数据库的操作,通过java程序,在本地开发和运行.整体为,Spark建立数据库连接,读取数据 ...
- Angular基础(七) HTTP & Routing
一.HTTP a)Angular提供了自己的HTTP库来调用外部API,为了能够在等待API响应的过程中继续与界面交互,采用异步HTTP请求的方式. b)Get请求,首先导入Http, Respo ...
- Jenkins报错'Gradle build daemon disappeared unexpectedly'的问题解决
在将项目集成到 Jenkins 后,经常会出现不稳定的构建,Jenkins 控制台输出的错误信息为:Gradle build daemon disappeared unexpectedly (it m ...
- 国网SGCC_UAP 反编译.class文件源代码
SGCC_UAP和eclipse操作方式差不多,对于用惯了IDEA和Android Studio的人来说非常不方便,按住Ctrl点击类名不能查看源码. 因为jar包下都是.class文件,所以需要安装 ...
- Flutter 安装
都说程序猿学习是不分平台的,做了一辈子的Xaml,也想看看现在最牛逼的移动技术. 看了看Google 的Flutter,好像很牛逼,不怎么需要Android和IOS基础(应该还是要的), 不过现在是B ...
- Java并发编程(四)synchronized
一.synchronized同步方法或者同步块 在了解synchronized关键字的使用方法之前,我们先来看一个概念:互斥锁,顾名思义:能到达到互斥访问目的的锁. 举个简单的例子:如果对临界资源加上 ...
- 框架模式MVC在安卓中的实践
我们采用ListView来演示我们的MVC模式,目录结构: 实体类:包含了书的名字和图片信息 public class Book { //书名 private String name; //书的图片 ...