使用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 = 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

时间: 2024-08-04 16:26:28

使用HttpClient和Jsoup实现一个简单爬虫的相关文章

[Java]使用HttpClient实现一个简单爬虫,抓取煎蛋妹子图

  第一篇文章,就从一个简单爬虫开始吧. 这只虫子的功能很简单,抓取到”煎蛋网xxoo”网页(http://jandan.net/ooxx/page-1537),解析出其中的妹子图,保存至本地. 先放结果: 从程序来讲,步骤分为三步: 1.发起一个http请求,获取返回的response内容: 2.解析内容,分离出有效图片的url: 3.根据这些图片的url,生成图片保存至本地. 开始详细说明: 准备工作:HttpClient的Jar包,访问http://hc.apache.org/   自行下

[python]做一个简单爬虫

为什么选择python,它强大的库可以让你专注在爬虫这一件事上而不是更底层的更繁杂的事 爬虫说简单很简单,说麻烦也很麻烦,完全取决于你的需求是什么以及你爬的网站所决定的,遇到的第一个简单的例子是paste.ubuntu.com 这是一个贴代码的网站,没事喜欢看看有没有什么好玩的东西,只是上面大部分都是minecraft的东西,于是写了以下代码 1 import urllib2 2 import socket 3 import re 4 def getData(url, timeOut = 10)

python3的一个简单爬虫

#coding=utf-8 import re import urllib.request def getHtml(url): page = urllib.request.urlopen(url) html = page.read() html = html.decode('UTF-8') return html #Urllib 模块提供读取页面数据的接口 #urllib.request.urlopen()方法用于打开一个url地址 #read()方法用于读取url上的数据 print(getH

零基础简单爬虫制作(以wjyt-china企业黄页爬虫为例)(上)

零.前言 本教程面向毫无编程基础的人群,讲述制作出爬虫所需要的最基本知识.目标是让你就算阅读代码如天书,凭借基本知识,复制代码以及使用搜索引擎也可以制作出可用的爬虫. 同时,本教程也是对笔者本人凭借基本知识,复制代码以及使用搜索引擎制作出可用爬虫的快速学习经历的总结归纳. 再同时,本教程也希望分享给读者三条快速学习哲学: 1.寻找趣味,保持专注.兴趣是最好的老师,发掘兴趣是最强的能力. 2.容忍无知,聚焦实用.在缺乏系统性知识的情况下,要快速涉猎不熟悉的领域并做出成果,需要控制知识与无知的平衡,

python 简单爬虫(beatifulsoup)

---恢复内容开始--- python爬虫学习从0开始 第一次学习了python语法,迫不及待的来开始python的项目.首先接触了爬虫,是一个简单爬虫.个人感觉python非常简洁,相比起java或其他面向对象的编程语言,动态语言不需要声明函数或变量类型.python有20年的发展历史,以简洁高效闻名,python最初只是一个马戏团的名字,它的哲学是'用一种方法完成一件事情'.我第一次使用python时就被它的简洁高效迷住了,相比起c++和java,他简直太棒了.而且现阶段的大数据和人工智能领

一个简单的多线程爬虫

   本文介绍一个简单的多线程并发爬虫,这里说的简单是指爬取的数据规模不大,单机运行,并且不使用数据库,但保证多线程下的数据的一致性,并且能让爬得正起劲的爬虫停下来,而且能保存爬取状态以备下次继续. 爬虫实现的步骤基本如下: 分析网页结构,选取自己感兴趣的部分; 建立两个Buffer,一个用于保存已经访问的URL,一个用户保存带访问的URL; 从待访问的Buffer中取出一个URL来爬取,保存这个URL中感兴趣的信息:并将这个URL加入已经访问的Buffer中,然后将这个URL中的所有外链URL

大数据之网络爬虫-一个简单的多线程爬虫

   本文介绍一个简单的多线程并发爬虫,这里说的简单是指爬取的数据规模不大,单机运行,并且不使用数据库,但保证多线程下的数据的一致性,并且能让爬得正起劲的爬虫停下来,而且能保存爬取状态以备下次继续. 爬虫实现的步骤基本如下: 分析网页结构,选取自己感兴趣的部分; 建立两个Buffer,一个用于保存已经访问的URL,一个用户保存带访问的URL; 从待访问的Buffer中取出一个URL来爬取,保存这个URL中感兴趣的信息:并将这个URL加入已经访问的Buffer中,然后将这个URL中的所有外链URL

利用HttpClient写的一个简单页面获取

之前就听说过利用网络爬虫来获取页面,感觉还挺有意思的,要是能进行一下偏好搜索岂不是可以满足一下窥探欲. 后来从一本书上看到用HttpClient来爬取页面,虽然也有源码,但是也没说用的HttpClient是哪个版本的,而且HttpClient版本不一样,导致后面很多类也不一样.于是下载了最新的HttpCient版本,并且对着tutorial和网上的文档试着写一个简单的获取页面的例子,最终证明是可行的,但是也遇到了不少问题,而且这个例子也十分简单. import java.io.IOExcepti

一个抓取知乎页面图片的简单爬虫

在知乎上看到一个问题  能利用爬虫技术做到哪些很酷很有趣很有用的事情?发现蛮好玩的,便去学了下正则表达式,以前听说正则表达式蛮有用处的,学完后觉得确实很实用的工具.问题评论下基本都是python写的爬虫,我看了下原理,感觉爬一个简单的静态网页还是挺容易的.就是获取网站html源码,然后解析需要的字段,最后拿到字段处理(下载).想起我学java的时候有个URL类好像有这个功能,便去翻了下api文档,发现URLConnection果然可以获取html源码. 首先从核心开始写,获取网页源码 packa