利用 Redis 实现一个爬虫系统循环代理池
2018-11-29 本文已影响15人
阿土伯已经不是我
前言
最近在实现爬虫系统的时候,用到了 http 代理。我有一系列的代理,使用的时候要在分布式的环境中实现循环的使用。这里我们就采用了 redis 的 list 数据结构来实现
redis list 命令解释
首先我们来看一下 redis list 支持的命令
redis 的队列实际上是队列和栈的混合体。支持左进右出、右进左出、左进左出、右进右出等操作。我们来看一下 redis list 支持的命令
命令 | 效果 |
---|---|
LPOP | 从队列左边取出一个元素 |
LPUSH | 向队列左边放入一个元素 |
LPUSHX | 如果队列存在,向队列左边放入一个元素 |
BLPOP | 阻塞模式从队列左边取出一个元素,如果没有元素则等待 |
RPOP | 从队列右边取出一个元素 |
RPUSH | 向队列右边放入一个元素 |
RPUSHX | 如果队列存在,向队列右边放入一个元素 |
BRPOP | 阻塞模式从队列右边取出一个元素,如果没有元素则等待 |
RPOPLPUSH | 原子操作,从一个队列右边取出一个元素放入另一个队列左边 |
BRPOPLPUSH | RPOPLPUSH的阻塞模式,当第一个队列不存在,则等待 |
LINDEX | 返回列表中指定下标的元素 |
LINSERT | 在队列指定的位置之前或者之后插入元素 |
LLEN | 返回队列的大小 |
LRANGE | 返回对了中指定范围的元素 |
LREM | 在队列中删除指定数量个指定值的元素 |
LSET | 设置队列中指定下标的元素的值 |
LTRIM | 裁剪队列,保留指定下标范围的元素 |
从上面的我们可以看出,如果我们调用 RPOPLPUSH 命令的时候,如果取出值的队列和放入值的队列是一个,就形成了一个循环队列,每次从队尾取出的元素放到队头,可以无限循环的依次从队列中取出不同的值。下面我们来演示一下
建立队列
首先,我们可以用 redis 命令行来建立一个代理池队列。这里用 PROXY1、PROXY2、PROXY3、PROXY4、PROXY5 示例代替代理的详细信息。实际工作中,我们可以用代理对象的 json 字符串来存储代理的信息。
登录 redis 后,切换到数据库 10 ,然后执行下面的命令来建立一个5个元素的队列
127.0.0.1:37382[10]> lpush PROXY_QUEUE PROXY1
(integer) 1
127.0.0.1:37382[10]> lpush PROXY_QUEUE PROXY2
(integer) 2
127.0.0.1:37382[10]> lpush PROXY_QUEUE PROXY3
(integer) 3
127.0.0.1:37382[10]> lpush PROXY_QUEUE PROXY4
(integer) 4
127.0.0.1:37382[10]> lpush PROXY_QUEUE PROXY5
(integer) 5
java 循环从队列中取数
首先引入 jedis 库
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
然后编写代码
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
jedisPoolConfig.setMaxIdle(5);
jedisPoolConfig.setMinIdle(1);
JedisPool jedisPool = new JedisPool(
jedisPoolConfig,
"ip",
port,
600,
"redispwd",
10,
"ProxyClient"
);
Jedis jedis = jedisPool.getResource();
while (true) {
System.out.println(jedis.rpoplpush("PROXY_QUEUE", "PROXY_QUEUE"));
}
这段代码连接 redis 服务器的 10 号数据库后,不停的从 PROXY_QUEUE 队列的右边取出元素并放到左边。并返回当前取出的元素。无限循环。
执行上述代码,输出为
PROXY1
PROXY2
PROXY3
PROXY4
PROXY5
PROXY1
PROXY2
PROXY3
PROXY4
PROXY5
PROXY1
PROXY2
PROXY3
...
这样,如果我们将 PROXY1 这些字符串换成 http 代理的配置信息,就可以依次循环从队列中取出一个新的 http 代理配置来执行我们的爬虫过程了。