爬虫(crawler):是一种按照一定的规则,自动抓取万维网信息的程序或者脚本

HttpClient方式


以get请求方式进行举例:
引入jar包:httpclient

  @Test
    public void test() throws Exception{
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建网络请求对象
        HttpGet httpGet = new HttpGet("http://www.oschina/");
        // 执行爬取,并且获得结果
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
        // 处理爬取结果
        if (httpResponse.getStatusLine().getStatusCode()==200){
            // 响应状态为200,处理爬取结果
            HttpEntity entity = httpResponse.getEntity();
            // 结果转化
            String toString = EntityUtils.toString(entity, "utf-8");
            System.out.println(toString);
        }
        // 关闭相关资源
        httpResponse.close();
        httpClient.close();
    }

Jsoup方式

引入jar包:jsoup -->commons-lang3+commons-io (工具包)
这是一款专门解析 html 页面的技术,所以有个硬性技能,就是要求会使用jquery\Selector选择器,否则标签你都选不对,更何况爬?
列举常用的规则:

tagname: 通过标签查找元素,比如:span
#id: 通过 ID 查找元素,比如:# city_1
.class: 通过 class 名称查找元素,比如:.class_a
[attribute]: 利用属性查找元素,比如:[abc]
[attr=value]: 利用属性值来查找元素,比如:[class=s_name]

列举几个复杂的组合选择:

el#id: 元素+ID,比如: h3#city_1
el.class: 元素+class,比如: li.class_a
el[attr]: 元素+属性名,比如: span[abc]
任意组合: 比如:span[abc].s_name
ancestor child: 查找某个元素下子元素,比如:.city_con li 查找"city_con"下的所有 li
parent > child: 查找某个父元素下的直接子元素,比如:
.city_con > ul > li 查找 city_con 第一级(直接子元素)的 ul,再找所有 ul 下的第一级 li
parent > *: 查找某个父元素下所有直接子元素

用法:

//el#id: 元素+ID,比如: h3#city_bj
String str = document.select("h3#city_bj").text();
//el.class: 元素+class,比如: li.class_a
str = document.select("li.class_a").text();
//el[attr]: 元素+属性名,比如: span[abc]
str = document.select("span[abc]").text();
//任意组合,比如:span[abc].s_name
str = document.select("span[abc].s_name").text();
....

jsoup 的主要功能如下:

  1. 从一个 URL,文件或字符串中解析 HTML;
  2. 使用 DOM 或 CSS 选择器来查找、取出数据;
  3. 可操作 HTML 元素、属性、文本;
 @Test
    public void test() throws Exception{
        // 解析url 地址
        Document document = Jsoup.parse(new URL("http://www.itcast/"), 1000);
        // 获取title的内容
        Element title = document.getElementsByTag("title").first();
        System.out.println(title.text());
    }

WebMagic爬虫框架

其底层使用的 HttpClient 和 Jsoup
所依赖的jar包:webmagic-core和webmagic-extension
WebMagic 四大组件: Downloader、PageProcessor、Scheduler、Pipeline


Downloader

发送请求的一个组件,任务是发送http请求获得(下载)Html页面,然后
封装成Page对象传递给PageProcessor,它其实就是对HttpClient对象
的封装

PageProcessor

PageProcessor 负责解析爬回的页面,一方面可以tongguocss选择
器去解析内容,另一方面在解析的过程中,如果解析到新的请求连接,
就会封装到Request对象中传递给Scheduler组件,最终再次发送请求,
爬取内容,其实就是对Jsoup的封装.
它对解析完的目的数据也会封装到ResultItems然后传递给Pipeline组
件.由Pipeline专门负责处理数据的储存问题.

Scheduler

它可接受Request对象请求连续保存,并且一次发送.
它会自动对装载的url进行去重.

Pipeline

它是将我们解析完的结果进行最终处理.(接口) :3种处理方式

 1. 将结果输出到控制台
 2. 将结果存入本地指定目录下
 3. 存入到数据库

用于数据流转的对象

Request

Request 是对 URL 地址的一层封装,一个 Request 对应
一个 URL 地址。它是 PageProcessor 与 Downloader 交
互的载体,也是 PageProcessor 控制Downloader 唯一方
式。

Page

Page 代表了从 Downloader 下载到的一个页面——可是 HTML,也可能是 JSON或者其他文本格式的内容。Page
是 WebMagic 抽取过程的核心对象,它提供一些方法可
供抽取、结果保存等。

ResultItems

ResultItems 相当于一个 Map,它保存 PageProcessor
处理的结果,供 Pipeline 使用。它的 API 与 Map 很类
似,值得注意的是它有一个字段 skip,若设置为 true,
则不应被 Pipeline 处理。


WebMagic 里主要使用了三种元素抽取技术:XPath、正
则表达式和 CSS 选择器

爬虫的配置/启动/终止

Spider 是爬虫启动的入口。在启动爬虫之前,我们需要使
用一个 PageProcessor创建一个 Spider 对象,然后使用
run()进行启动。

方法说明示例
create(PageProcessor)创建 SpiderSpider.create(new GithubRepoProcessor())
addUrl(String…)添加初始的 URLspider .addUrl(“http://webmagic.io/docs/”)
thread(n)开启 n 个线程spider.thread(5)
run()启动,会阻塞当前线程执行spider.run()
start()/runAsync()异步启动,当前线程继续执行spider.start()
stop()停止爬虫spider.stop()
addPipeline(Pipeline)添加一个 Pipeline,一个 Spider可以有多个 Pipelinespider .addPipeline(new ConsolePipeline())
get(string)同步调用,并直接取得结果ResultItems result = spider.get(“http://webmagic.io/docs/”)
getAll(String…)同步调用,并直接取得一堆结果List results = spider .getAll(“http://webmagic.io/docs/","http://webmagic.io/xxx”)

**Site.me()**可以对爬虫进行一些配置配置,包括编码、抓取间隔、超时时间、重试次数等。

private Site site = Site.me()
 .setCharset("UTF-8")//编码
 .setSleepTime(1)//抓取间隔时间
 .setTimeOut(1000*10)//超时时间
 .setRetrySleepTime(3000)//重试时间
 .setRetryTimes(3);//重试次数
 .setDomain("GitHub")//设置域名
 .setHttpProxy(new HttpHost("127.0.0.1",8080))//设置Http代理
 .addHeader("Referer","https://github")//添加一条addHeader
 .addCookie("dotcomt_user","code4craft") // 添加一条cookie

爬虫分类

网络爬虫按照系统结构和实现技术,大致可以分为以下几种类型:通用网络爬虫、聚焦网络爬虫、增量式网络爬虫、深层网络爬虫。
通用网络爬虫:就是互联网上抓取所有数据。
聚焦网络爬虫:互联网上只抓取某一种数据。
增量式网络爬虫:互联网上只抓取刚刚更新的数据。
深层网络(Deep Web)爬虫:Deep Web 是那些大部分内容不能通过静态链接获取的、隐藏在搜索表单后
的,只有用户提交一些关键词才能获得的 Web 页面。

拓展

爬回的数据去重方式

  • HashSet

使用 java 中的 HashSet 不能重复的特点去重。优点是容易理解。使用方便。
缺点:占用内存大,性能较低。

  • Redis 去重

使用 Redis 的 set 进行去重。优点是速度快(Redis 本身速度就很快),而且
去重不会占用爬虫服务器的资源,可以处理更大数据量的数据爬取。
缺点:需要准备 Redis 服务器,增加开发和使用成本。

  • 布隆过滤器(BloomFilter)

使用布隆过滤器也可以实现去重。优点是占用的内存要比使用 HashSet
要小的多,也适合大量数据的去重操作。
缺点:有误判的可能。没有重复可能会判定重复,但是重复数据一定会
判定重复。

更多推荐

Java实现爬虫