首页 > 代码库 > 使用HttpClient和Jsoup实现一个简单爬虫
使用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解析。
直接上代码吧:这基本上是一个通用的类了,给定一个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"); } }
爬取图片:
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 = http://www.mamicode.com/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
使用HttpClient和Jsoup实现一个简单爬虫