利用 Redis 實現一個爬蟲系統迴圈代理池
前言
最近在實現爬蟲系統的時候,用到了 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 代理配置來執行我們的爬蟲過程了。