代码思想主要是广度优先搜索,有不了解的同学可以下去了解一下算法思想,我们直接来看代码: redis数据库爬虫队列代码: package redisqueue; import redis.clients.jedis.Jedis; /** * Created by hg_yi on 17-6-12. */ public class RedisQueue { private Jedis jedis = null; //本地redis数据库链接服务 public RedisQueue() { //连接本地的 Redis 服务 jedis = new Jedis("127.0.0.1", 6379); //权限认证 jedis.auth("******"); } //将未访问的url加入到toVisit表中(使用的是尾插法) public void addToVisit(String url) { jedis.rpush("to 继续阅读 >>


董恒毅 17/06/12 20:48:40
注:本篇博客的所有测试环境均为Ubuntu16.04之下,本篇博客总结自Redis教程。 数据库的安装与配置 Ubuntu下安装 $sudo apt-get update $sudo apt-get install redis-server 服务端启动命令 redis-server 客户端启动命令 redis-cli 启动成功之后会出现: redis 127.0.0.1:6379> 在终端上输入ping命令,如果出现pong则说明安装成功。 设置redis数据库可远程登录并设置登录密码 使用root权限修改/etc/redis/redis.conf文件: 想使用哪个密码进行登录就直接修改“password”这个字符串就行,如图我现在的密码是password。 设置允许远程登录: 将bind 127.0.0.1那一行进行注释。 修改完之后将redis服务进行重启: sudo /etc/init.d/redis-server r 继续阅读 >>


董恒毅 17/06/07 20:32:02
简介布隆过滤器 当我们要对海量url进行抓取的时候,我们常常关心一件事,就是url的去重问题,对已经抓取过的url我们不需要在进行重新抓取。在进行url去重的时候,我们的基本思路是将拿到的url与已经抓取过的url队列进行比对,看当前url是否在此队列中,如果在已抓取过的队列中,则将此url进行舍弃,如果没有在,则对此url进行抓取。看到这,如果有哈希表基础的同学,很自然的就会想到那么如果用哈希表对url进行存储管理的话,那么我们对于url去重直接使用HashSet进行url存储不就行了,事实上,在url非海量的情况下,这的确是一种很不错的方法,但哈希表的缺点很明显:费存储空间。 举个例子: 对于像Gmail那样公众电子邮件提供商来说,总是需要过滤掉来自发送垃圾邮件的人和来及邮件的E-mail地址。然而全世界少说也有几十亿个发垃圾邮件的地址,将他们都存储起来需要大量的网络服务器。如果用哈希表,每存储一亿个E-mail地址,就需要1.6GB的内存(用哈希表实现的具体实现方式是将每一个E-mail地址对应成一个八字节的信息指纹,然后将这个信息存储哈希表,但是 继续阅读 >>


董恒毅 17/06/06 19:40:14
Servlet初始化过程、ServletConfig 每个Servlet都必须由Web容器读取Servlet设置的信息,初始化等,才能生成对应的Servlet实例。对于每个Servlet的设置信息,Web容器都会为其生成一个ServletConfig作为代表对象。 在Servlet接口上,定义了与Servlet生命周期及请求服务相关的init,service,destroy三个方法。每一次请求来到容器时,会产生HttpServletRequest,HttpServletResponse对象,并调用service方法时当做参数传入。 在Web容器启动后,根据上面所说,会产生一个ServletConfig对象,而后调用init方法并将产生的ServletConfig对象传入其中,这个过程在创建Servlet实例之后只会发生一次,之后每次请求到来,就只调用Servlet的service方法进行服务。 Servlet类架构图: 在Java中,当我们想要在对象实例化后做一些操作,必须定义构造器,然而在JavaWeb中则不然,当我们想要使用ServletCo 继续阅读 >>


董恒毅 17/06/05 21:55:02
平常我们在浏览网页的时候,会有一些网站要求我们进行登录,当我们成功登录之后,会发现我们所浏览的所有相关网页都不再需要我们重新登录,这是为什么呢。还有当我们在电商平台进行购物的时候,我们虽然是在同一家电商平台进行购物,但是我们明明是在不同的页面进行的添加购物车的选项,为什么最后我们可以在购物车中找到我们所添加的所有商品呢。其实,这些都是我们在Web后台方面使用了Cookie技术。 Cookie简介 Cookie定义:Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。 session:会话,指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间。具体到Web中的Session指的就是用户在浏览某个网站时,从进入网站到关闭浏览器所经过的这段时间,也就是用户浏览这个网站所花费的时间。(摘自百度百科) 实现思想 如何让网站记住我们,乃至记住我们之前做过的事情,我们可以联想,如果让服务器在我们进行此次请求的时候,可 继续阅读 >>


董恒毅 17/06/04 00:17:32
我们喜欢使用数组进行数据的查找,就是因为数组是一种“随机存取”的数据结构,我们根据数组的起始地址和数组元素的下标值就可以直接计算出每一个数组元素的存储位置,所以它的查找时间是O(1),而与数组的个数无关。 我们在这个思想的基础上,可以联想到,如果有一种数据结构,让我们在进行关键字查找的时候,不用在类似于数组这样的数据结构上进行遍历与比较就可以直接通过某种关系就可以查找到该关键字在数组中的位置,使其时间复杂度从O(n)降到O(1),那就可以大大提高查找的效率。我们的前辈们基于这种想法发明了散列方法,也就是哈希或关键字地址计算方法。 基本思想 我们试图寻找一种关系,可以根据我们要存储的关键字(key)然后使用这种关系直接计算出它应该存储的位置(p),一旦建立起这种关系,那么我们在之后一旦需要查找此关键字的话,只需计算此对应关系所产生的值就可以直接得到关键字所在的地址,那么查找的时间复杂度也就降到了O(1),我们将刚才所说的转换为一种数学关系: p(位置)= H(key) 其中H就是对应关系,我们称之为哈希函数,p被成为散列地址。因此,哈希 继续阅读 >>


董恒毅 17/06/01 22:12:17
原作者:海子 出处:http://www.cnblogs.com/dolphin0520/     本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。 那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务? 在Java中可以通过线程池来达到这样的效果。今天我们就来详细讲解一下Java的线程池,首先我们从最核心的ThreadPoolExecutor类中的方法讲起,然后再讲述它的实现原理,接着给出了它的使用示例,最后讨论了一下如何合理配置线程池的大小。 以下是本文的目录大纲: 一.Java中的ThreadPoolExecutor类 二.深入剖析线程池实现原理 三.使用示例 继续阅读 >>


董恒毅 17/05/31 20:47:24
本文转载至:残剑 如果面试官问Integer与int的区别:估计大多数人只会说道两点,Ingeter是int的包装类,int的初值为0,Ingeter的初值为null。但是如果面试官再问一下Integer i = 1;int ii = 1; i==ii为true还是为false?估计就有一部分人答不出来了,如果再问一下其他的,估计更多的人会头脑一片混乱。所以我对它们进行了总结,希望对大家有帮助。 首先看代码: 1 package com.test; 2 /** 3 * 4 * @author 刘玲 5 * 6 */ 7 public class TestInteger { 8 9 /** 10 * @param args 11 */ 12 public static void main(String[] args) { 13 int i = 128; 14 Integer i2 = 128; 15 Integer i3 = new Int 继续阅读 >>


董恒毅 17/05/29 22:51:31
除过正则表达式的基本概念与特性还有使用方法之外,我们在解析html的时候,如果要进行字符串的匹配,必须还要熟悉正则表达式之中量词的使用法则,今天我们就来谈谈贪婪、逐步、独吐这三种量词的使用。 贪婪量词 我们先来看一下经常使用的贪婪量词都有哪些: X?: X项目(项目也可以理解为X代表的变量,项目比较准确)出现一次或没有。 X*: X项目出现0次或多次。 X+: X项目至少出现1次。 X{n}: X项目出现n次。 X{n, }: X项目至少出现n次。 X{n, m}: X项目出现n次但不超过m次。 下来我们解释贪婪量词为何贪婪。当我们使用贪婪量词进行字符串匹配的时候,如果比较器(Matcher)看到贪婪量词,会将剩下的字符串全部吃掉,然后从字符串的末尾一个个再吐出来,在这个过程中,它还会将吐出来的字符与规则表达式进行比较,如果吐出来的字符串符合规则表达式,而吃下的字符串也符合贪婪量词那么就比较成功,我们可以预想到,贪婪量词之所以贪婪,就是因为它会尽可能的找出长度最长的符合文字。 举个例子: 文字:xf 继续阅读 >>


董恒毅 17/05/28 23:01:57
声明:如需转载本篇文章,请进行私聊并在文章首处注明出处,本代码未经授权不可用于获取商业价值,否则后果将由自己承担。 这次的需求大概是从百度图片里面抓取任意的分类的图片,考虑到有些图片的资源不是很好,并且由于百度搜索越到后面相关度会越来越低,所以我将每个分类要爬的数据量控制在了600,实际爬下来,每个分类也就是500左右的图片。 实现架构 先来看一下本次代码的实现架构: htmlparse里面的两个类主要负责对网页进行请求以返回实体,并且对实体进行解析,拿到自己想要的json数据和每个图片的链接。 httpbrowser里面主要构建了要爬取的url,从百度图片的分页到具体的每个图片的url。 mainmethon主要就是main方法了。 savefile主要是将爬取的图片进行文件的保存,以每个图片的url最后面的一串字符串为文件名,然后将它保存到自己创建的目录之中。 我们来看一下main方法: package mainmethon; import httpbrowser.CreateUrl; impo 继续阅读 >>


董恒毅 17/05/21 02:05:27