模塊三 第二週 作業三 分佈式scrapy-redis

1 問題描述

將Scrapy抓取必聯網項目升級爲Scrapy‐Redis分佈式爬蟲,並完成代理IP池proxyPool的開發

  1. 完成Scrapy‐Redis組件的安裝
  2. 完成代理IP池proxyPool的開發
  3. 將必聯網爬蟲項目升級爲Scapy‐Redis分佈式爬蟲
  4. 分佈式爬蟲在中間件中設置代理要通過代理IP池來獲取,而不是每次請求都訪問第三方代理IP 接口

2 解題提示

  1. 普通的Scrapy項目升級升Scarpy‐Redis分佈式爬蟲,只需要在Settings中加入4局配置
  2. 可以用Redis中的集合對象來存儲第三方返回的代理IP地址,間隔時間訪問第三方代理IP接口,緩存記錄上次的代理IP內容,當接口返回新的代理IP時,更新Redis中的數據

3 評分標準

  1. 完成Scrapy‐Redis的配置10分
  2. 代理Ip池的開發 10分
  3. 代碼註釋,規範10分

4 要點解析

  • 分佈式爬蟲

在這裏插入圖片描述

5 實現步驟

  • 連接redis
# 啓動Scrapy-Redis去重過濾器,取消Scrapy的去重功能
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 啓用Scrapy-Redis的調度器,取消Scrapy的調度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# Scrapy-Redis斷點續爬
SCHEDULER_PERSIST = True
# 配置Redis數據庫的連接
REDIS_URL = 'redis://127.0.0.1:6379'
  • 分佈式中使用代理
import urllib.request as ur
import redis
import time


class Proxypool():
    def __init__(self):
        # 構造redis連接對象
        self.redis_conn = redis.StrictRedis(
            host='localhost',
            port='6379',
            decode_responses=True
        )

    def set_proxy(self):
        proxy_old = None
        # 循環更新代理ip
        while True:
            # 通過接口獲取ip
            proxy_new = 'http://' + ur.urlopen(
                'http://api.ip.data5u.com/dynamic/get.html?order=2c45db33eaaa2216a2e39c2b1905dc4f&sep=3').read().decode(
                'utf-8').strip()
            # 判斷代理是否發生變化
            if proxy_new != proxy_old:
                # 賦值新的代理
                proxy_old = proxy_new
                # 刪除proxy的值
                self.redis_conn.delete('proxy')
                # 像redis中添加 代理   *proxy_new與 proxy_new
                self.redis_conn.sadd('proxy', proxy_new)
                time.sleep(1)
                break
            else:
                time.sleep(2)

    def get_proxy(self):
        # 獲取ip列表
        proxy_s = self.redis_conn.smembers('proxy')
        # 把ip拿出來
        for proxy in proxy_s:
            # 有值
            if proxy:
                return proxy
            else:
                time.sleep(2)
                return self.get_proxy()

    def kaishi(self):
        self.set_proxy()
        return self.get_proxy()
if __name__ == '__main__':
    print(Proxypool().kaishi())
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章