Scrapy框架之基於RedisSpider實現的分布式爬蟲


需求:爬取的是基於文字的網易新聞數據(國內、國際、軍事、航空)。
  基於Scrapy框架代碼實現數據爬取后,再將當前項目修改為基於RedisSpider的分布式爬蟲形式。

一、基於Scrapy框架數據爬取實現

1、項目和爬蟲文件創建

$ scrapy startproject wangyiPro
$ cd wangyiPro/
$ scrapy genspider wangyi news.163.com    # 基於scrapy.Spider創建爬蟲文件

2、爬蟲文件編寫——解析新聞首頁獲取四個板塊的url

import scrapy

class WangyiSpider(scrapy.Spider):
    name = 'wangyi'
    # allowed_domains = ['news.163.com']
    start_urls = ['https://news.163.com/']

    def parse(self, response):
        lis = response.xpath('//div[@class="ns_area list"]/ul/li')
        # 獲取指定的四個列表元素(國內3、國際5、軍事6、航空7)
        indexes = [3, 4, 6, 7]
        li_list = []   # 四個板塊對應的li標簽對象
        for index in indexes:
            li_list.append(lis[index])

        # 獲取四個板塊中的超鏈和文字標題
        for li in li_list:
            url = li.xpath('./a/@href').extract_first()
            title = li.xpath('./a/text()').extract_first()   # 板塊名稱

            print(url + ":" + title)   # 測試

  執行爬蟲文件,控制台打印輸出四個url,說明解析成功:

$ scrapy crawl wangyi --nolog
http://news.163.com/domestic/:國內
http://news.163.com/world/:國際
http://war.163.com/:軍事
http://news.163.com/air/:航空

3、爬蟲文件編寫——對每個板塊url發請求,進一步解析

import scrapy

class WangyiSpider(scrapy.Spider):
    name = 'wangyi'
    # allowed_domains = ['news.163.com']
    start_urls = ['https://news.163.com/']

    def parse(self, response):
        lis = response.xpath('//div[@class="ns_area list"]/ul/li')
        # 獲取指定的四個列表元素(國內3、國際5、軍事6、航空7)
        indexes = [3, 4, 6, 7]
        li_list = []   # 四個板塊對應的li標簽對象
        for index in indexes:
            li_list.append(lis[index])

        # 獲取四個板塊中的超鏈和文字標題
        for li in li_list:
            url = li.xpath('./a/@href').extract_first()
            title = li.xpath('./a/text()').extract_first()   # 板塊名稱

            """對每一個板塊對應url發起請求,獲取頁面數據"""
            # 調用scrapy.Request()方法發起get請求
            yield scrapy.Request(url=url, callback=self.parseSecond)

    def parseSecond(self, response):
        """聲明回調函數"""
        # 找到頁面中新聞的共有標簽類型,排除廣告標簽
        div_list = response.xpath('//div[@class="data_row news_article clearfix"]')
        print(len(div_list))   # 非空則驗證xpath是正確的
        for div in div_list:
            # 文章標題
            head = div.xpath('.//div[@class="news_title"]/h3/a/text()').extract_first()
            # 文章url
            url = div.xpath('.//div[@class="news_title"]/h3/a/@href').extract_first()
            # 縮略圖
            imgUrl = div.xpath('./a/img/@src').extract_first()
            # 發布時間和標簽:提取列表中所有的元素
            tag = div.xpath('.//div[@class="news_tag"]//text()').extract()
            # 列表裝化為字符串
            tag = "".join(tag)

  編寫到這里時,再次執行爬蟲腳本,會發現print(len(div_list))輸出的是4個0,但是xpath表達式卻是正確的。
  這是由於新浪網的新聞列表信息是動態加載的,而爬蟲程序向url發請求無法獲取動態加載的頁面信息。
  因此需要selenium幫忙在程序中實例化一個瀏覽器對象,由瀏覽器對象向url發請求,再通過調用page_source屬性拿到selenium實例化對象中獲取的頁面數據,這個數據中包含動態加載的數據內容。

二、將selenium應用到Scrapy項目中

  需求分析:當點擊國內超鏈進入國內對應的頁面時,會發現當前頁面展示的新聞數據是被動態加載出來的,如果直接通過程序對url進行請求,是獲取不到動態加載出的新聞數據的。則就需要我們使用selenium實例化一個瀏覽器對象,在該對象中進行url的請求,獲取動態加載的新聞數據。
  響應對象response從下載器傳給Spiders爬蟲文件時,一定會穿過下載中間件。
  可以在下載中間件對響應對象進行攔截,對響應對象中存儲的頁面數據進行篡改,將動態加載的頁面數據加入到響應對象中。
  通過selenium可以篡改響應數據,並將頁面數據篡改成攜帶了新聞數據的數據。

1、selenium在scrapy中使用原理

  當引擎將國內板塊url對應的請求提交給下載器后,下載器進行網頁數據的下載,然后將下載到的頁面數據,封裝到response中,提交給引擎,引擎將response在轉交給Spiders。
  Spiders接受到的response對象中存儲的頁面數據里是沒有動態加載的新聞數據的。要想獲取動態加載的新聞數據,則需要在下載中間件中對下載器提交給引擎的response響應對象進行攔截,切對其內部存儲的頁面數據進行篡改,修改成攜帶了動態加載出的新聞數據,然后將被篡改的response對象最終交給Spiders進行解析操作。

2、selenium在scrapy中使用流程總結

(1)在爬蟲文件中導入webdriver類

from selenium import webdriver

(2)重寫爬蟲文件的構造方法
  在構造方法中使用selenium實例化一個瀏覽器對象(因為瀏覽器對象只需要被實例化一次)

class WangyiSpider(scrapy.Spider):
    def __init__(self):
        # 實例化瀏覽器對象(保證只會被實例化一次)
        self.bro = webdriver.Chrome(executable_path='/Users/hqs/ScrapyProjects/wangyiPro/wangyiPro/chromedriver')

(3)重寫爬蟲文件的closed(self,spider)方法
  在其內部關閉瀏覽器對象。該方法是在爬蟲結束時被調用。

class WangyiSpider(scrapy.Spider):
    def closed(self, spider):
        # 必須在整個爬蟲結束后關閉瀏覽器
        print('爬蟲結束')
        self.bro.quit()   # 瀏覽器關閉

(4)重寫下載中間件的process_response方法
  讓process_response方法對響應對象進行攔截,並篡改response中存儲的頁面數據。

(5)在配置文件中開啟下載中間件

3、項目代碼示例

(1)引入selenium定義瀏覽器開啟和關閉

import scrapy
from selenium import webdriver
from wangyiPro.items import WangyiproItem

class WangyiSpider(scrapy.Spider):
    name = 'wangyi'
    # allowed_domains = ['news.163.com']
    start_urls = ['https://news.163.com/']

    def __init__(self):
        # 實例化瀏覽器對象(保證只會被實例化一次)
        self.bro = webdriver.Chrome(executable_path='./wangyiPro/chromedrive')


    def closed(self, spider):
        # 必須在整個爬蟲結束后關閉瀏覽器
        print('爬蟲結束')
        self.bro.quit()   # 瀏覽器關閉

(2)使用下載中間件攔截settings.py修改

# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
    'wangyiPro.middlewares.WangyiproDownloaderMiddleware': 543,
}

(3)在下載中間件中進行攔截

  讓瀏覽器對象去發起get請求,獲取四大版塊對應的頁面數據,瀏覽器對url發送請求,瀏覽器是可以獲取到動態加載的頁面數據的。
  獲取到這部分動態數據后,可以將這部分數據裝回到攔截的response對象中去。然后將篡改好的response對象發給Spiders。
  Spiders接收到response對象后,將response賦值給回調函數parseSecond的response參數中。
  middlewares.py內容如下所示:

# 下載中間件
from scrapy.http import HtmlResponse   # 通過這個類實例化的對象就是響應對象
import time

class WangyiproDownloaderMiddleware(object):
    def process_request(self, request, spider):
        """
        可以攔截請求
        :param request:
        :param spider:
        :return:
        """
        return None

    def process_response(self, request, response, spider):
        """
        可以攔截響應對象(下載器傳遞給Spider的響應對象)
        :param request: 響應對象對應的請求對象
        :param response: 攔截到的響應對象
        :param spider: 爬蟲文件中對應的爬蟲類的實例
        :return:
        """
        print(request.url + "這是下載中間件")
        # 響應對象中存儲頁面數據的篡改
        if request.url in ['http://news.163.com/domestic/', 'http://news.163.com/world/', 'http://war.163.com/', 'http://news.163.com/air/']:
            # 瀏覽器請求發送(排除起始url)
            spider.bro.get(url=request.url)
            # 滾輪拖動到底部會動態加載新聞數據,js操作滾輪拖動
            js = 'window.scrollTo(0, document.body.scrollHeight)'  # 水平方向不移動:0;豎直方向移動:窗口高度
            spider.bro.execute_script(js)  # 拖動到底部,獲取更多頁面數據
            time.sleep(2)  # js執行給頁面2秒時間緩沖,讓所有數據得以加載
            # 頁面數據page_text包含了動態加載出來的新聞數據對應的頁面數據
            page_text = spider.bro.page_source
            # current_url就是通過瀏覽器發起請求所對應的url
            # body是當前響應對象攜帶的數據值
            return HtmlResponse(url=spider.bro.current_url, body=page_text, encoding="utf-8", request=request)
        else:
            # 四個板塊之外的響應對象不做修改
            return response   # 這是原來的響應對象

三、爬蟲代碼完善及item處理

1、爬蟲文件

import scrapy
from selenium import webdriver

from wangyiPro.items import WangyiproItem


class WangyiSpider(scrapy.Spider):
    name = 'wangyi'
    # allowed_domains = ['news.163.com']
    start_urls = ['https://news.163.com/']

    def __init__(self):
        # 實例化瀏覽器對象(保證只會被實例化一次)
        self.bro = webdriver.Chrome(executable_path='/Users/hqs/ScrapyProjects/wangyiPro/wangyiPro/chromedriver')

    def closed(self, spider):
        # 必須在整個爬蟲結束后關閉瀏覽器
        print('爬蟲結束')
        self.bro.quit()   # 瀏覽器關閉

    def parse(self, response):
        lis = response.xpath('//div[@class="ns_area list"]/ul/li')
        # 獲取指定的四個列表元素(國內3、國際5、軍事6、航空7)
        indexes = [3, 4, 6, 7]
        li_list = []   # 四個板塊對應的li標簽對象
        for index in indexes:
            li_list.append(lis[index])

        # 獲取四個板塊中的超鏈和文字標題
        for li in li_list:
            url = li.xpath('./a/@href').extract_first()
            title = li.xpath('./a/text()').extract_first()   # 板塊名稱

            """對每一個板塊對應url發起請求,獲取頁面數據"""
            # 調用scrapy.Request()方法發起get請求
            yield scrapy.Request(url=url, callback=self.parseSecond, meta={'title': title})

    def parseSecond(self, response):
        """聲明回調函數"""
        # 找到頁面中新聞的共有標簽類型,排除廣告標簽
        div_list = response.xpath('//div[@class="data_row news_article clearfix"]')
        # print(len(div_list))   # 非空則驗證xpath是正確的
        for div in div_list:
            # 文章標題
            head = div.xpath('.//div[@class="news_title"]/h3/a/text()').extract_first()
            # 文章url
            url = div.xpath('.//div[@class="news_title"]/h3/a/@href').extract_first()
            # 縮略圖
            imgUrl = div.xpath('./a/img/@src').extract_first()
            # 發布時間和標簽:提取列表中所有的元素
            tag = div.xpath('.//div[@class="news_tag"]//text()').extract()

            # 列表裝化為字符串
            tags = []
            for t in tag:
                t = t.strip(' \n \t')   # 去除空格 \n換行 \t相當於tab
                tags.append(t)   # 重新裝載到列表中
            tag = "".join(tags)

            # 獲取meta傳遞的數據值
            title = response.meta['title']

            # 實例化item對象,將解析到的數據值存儲到item對象中
            item = WangyiproItem()
            item['head'] = head
            item['url'] = url
            item['imgUrl'] = imgUrl
            item['tag'] = tag
            item['title'] = title

            # 對url發起請求,獲取對應頁面中存儲的新聞內容數據
            yield scrapy.Request(url=url, callback=self.getContent, meta={"item":item})

    def getContent(self, response):
        """新聞內容解析的回調函數"""
        # 獲取傳遞過來的item對象
        item = response.meta['item']

        # 解析當前頁碼中存儲的頁面數據
        # 由於新聞的段落可能有多個,每個段落在一個p標簽中。因此使用extract()方法
        content_list = response.xpath('//div[@class="post_text"]/p/text()').extract()

        # 列表轉字符串(字符串才能保持在item對象中)
        content = "".join(content_list)
        item["content"] = content

        # item對象提交給管道
        yield item

注意:

(1)將解析到的數據值存儲到item對象

  由於爬蟲做了兩次解析,因此如何將第一次解析的數據加入item對象是最大的難點。
  解決方法:meta屬性請求傳參。

# 對url發起請求,獲取對應頁面中存儲的新聞內容數據
yield scrapy.Request(url=url, callback=self.getContent, meta={"item":item})

  對文章url發起請求,欲獲取對應頁面中存儲的新聞內容數據,調用新的回調函數getContent。

(2)新聞內容解析后將item對象提交給管道

class WangyiSpider(scrapy.Spider):
    """同上省略"""
    def getContent(self, response):
        """新聞內容解析的回調函數"""
        # 獲取傳遞過來的item對象
        item = response.meta['item']

        # 解析當前頁碼中存儲的頁面數據
        # 由於新聞的段落可能有多個,每個段落在一個p標簽中。因此使用extract()方法
        content_list = response.xpath('//div[@class="post_text"]/p/text()').extract()

        # 列表轉字符串(字符串才能保持在item對象中)
        content = "".join(content_list)
        item["content"] = content

        # item對象提交給管道
        yield item

2、items.py文件

import scrapy

class WangyiproItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    head = scrapy.Field()
    url = scrapy.Field()
    imgUrl = scrapy.Field()
    tag = scrapy.Field()
    title = scrapy.Field()
    content = scrapy.Field()

3、管道文件pipeline.py處理

(1)pipelines.py

class WangyiproPipeline(object):
    def process_item(self, item, spider):
        print(item['title']+ ':'+ item['content'])
        return item

(2)settings.py中放開管道

# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
    'wangyiPro.pipelines.WangyiproPipeline': 300,
}

(3)執行爬蟲輸出爬取的新聞信息

爬取結果
  

四、UA池和代理池在Scrapy中應用

1、下載中間件介紹

  下載中間件(Downloader Middlewares) 位於scrapy引擎和下載器之間的一層組件。

  • 作用:

  (1)引擎將請求傳遞給下載器過程中, 下載中間件可以對請求進行一系列處理。比如設置請求的 User-Agent,設置代理等

  (2)在下載器完成將Response傳遞給引擎中,下載中間件可以對響應進行一系列處理。比如進行gzip解壓等。

  我們主要使用下載中間件處理請求,一般會對請求設置隨機的User-Agent ,設置隨機的代理。目的在於防止爬取網站的反爬蟲策略。

2、UA池:User-Agent池

  • 作用:盡可能多的將scrapy工程中的請求偽裝成不同類型的瀏覽器身份。

  • 操作流程:

    1.在下載中間件中攔截請求

    2.將攔截到的請求的請求頭信息中的UA進行篡改偽裝

    3.在配置文件中開啟下載中間件

  • 代碼實現:

# 在middlewares.py中單獨給UA池封裝一個下載中間件的類
from scrapy.contrib.downloadermiddleware.useragent import UserAgentMiddleware
import random

class RandomUserAgent(UserAgentMiddleware):   # 繼承UserAgentMiddleware
    def process_request(self, request, spider):
        """每次攔截請求,都會從列表中隨機抽選一個ua賦值給當前攔截的請求"""
        # 從列表中隨機抽選出一個ua值
        ua = random.choice(user_agent_list)
        # 請求頭信息設置,賦值隨機抽取的ua(當前攔截請求ua寫入操作)
        request.headers.setdefault('User-Agent', ua)

user_agent_list = [
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 "
        "(KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
        "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 "
        "(KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 "
        "(KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 "
        "(KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 "
        "(KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 "
        "(KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 "
        "(KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 "
        "(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 "
        "(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]

3、代理池

  • 作用:盡可能多的將scrapy工程中的請求的IP設置成不同的。

  • 操作流程:

    1.在下載中間件中攔截請求

    2.將攔截到的請求的IP修改成某一代理IP

    3.在配置文件中開啟下載中間件

  • 代碼實現:

# 在middlewares.py中單獨給代理池封裝一個下載中間件的類
# 批量對攔截的請求進行Ip更換
class Proxy(object):
    def process_request(self, request, spider):
        # 對攔截到的請求url進行判斷(協議頭到底是http還是https)
        # 代理IP對協議頭有嚴格區分
        # request.url返回值形式:http://www.xxx.com/
        h = request.url.split(":")[0]   # 切割獲取協議頭
        if h == "https":
            ip = random.choice(PROXY_https)
            # 利用meta修改代理ip
            request.meta['proxy'] = 'https://' + ip
        else:
            ip = random.choice(PROXY_http)
            request.meta['proxy'] = 'http://' + ip

# 可被選用的代理IP——去www.goubanjia.com獲取免費代理IP
PROXY_http = [
    '153.180.102.104:80',
    '195.208.131.189:56055',
]
PROXY_https = [
    '120.83.49.90:9000',
    '95.189.112.214:35508',
]

  注意:請求url的協議頭到底是http還是https。

4、settings.py中開啟ua池、代理池

# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
    'wangyiPro.middlewares.WangyiproDownloaderMiddleware': 543,
    'wangyiPro.middlewares.RandomUserAgent': 542,
    'wangyiPro.middlewares.Proxy': 541,
}

5、總結

  每發一個請求,這個請求都會被中間件攔截,對當前請求的ip和user-agent進行更換。
  目的是攻克網站的反爬機制,因為每發一個請求,它的代理ip和ua都是不一樣的,門戶網站就很難發現當前爬取的載體是一個爬蟲。

五、基於RedisSpider分布式爬蟲實現

1、爬蟲類代碼修改

(1)導包並修改爬蟲類父類

from scrapy_redis.spiders import RedisSpider 

# class WangyiSpider(scrapy.Spider):
class WangyiSpider(RedisSpider):

  注意:這里將爬蟲類的父類,修改成RedisSpider。

(2)注釋start_urls,以redis_key代替

# start_urls = ['https://news.163.com/']
redis_key = 'wangyi'

  redis_key屬性:表示調度器隊列的名稱。

2、redis數據庫配置文件redis.conf配置

# 不注釋時,只允許本機的客戶端連接
# bind 127.0.0.1

# yes改為no,關閉redis的保護模式,客戶端可以對服務器進行讀寫操作
protected-mode  no

3、項目settings.py配置

(1)爬蟲程序不在redis本機時,指定redis地址

  管道默認會連接且將數據存儲到本機的redis服務中,如果想要連接存儲到其他redis服務中需要在settings.py中進行如下配置

# 如果redis服務器不在自己本機,則需要做如下配置
REDIS_HOST = '192.168.31.31' # redis數據庫所在機器的Ip地址
REDIS_PORT = 6379
# 可選配置
# REDIS_ENCODING = 'utf-8'
# REDIS_PARAMS = {'password':'123456'}   # 如果redis數據庫有密碼時配置

(2)使用scrapy-redis組件中封裝好的管道

  使用scrapy-redis組件中封裝好的可以被共享的管道。
  可以將每台機器爬取到的數據存儲通過該管道存儲到redis數據庫中,從而實現了多台機器的管道共享。

# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
    # 'wangyiPro.pipelines.WangyiproPipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400,
}

(3)使用scrapy-redis組件中封裝好的調度器

  使用scrapy-redis組件中封裝好的調度器,將所有的url存儲到該指定的調度器中,從而實現了多台機器的調度器共享。
  以下代碼可在settings.py中任意位置粘貼:

# 使用scrapy-redis組件的去重隊列
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis組件自己的調度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"   # 核心配置
# 是否允許暫停
SCHEDULER_PERSIST = True   # 值為True表示:宕機恢復服務時,從宕機的那個地方開始爬取,不用從頭開始

4、項目運行

(1)基於配置文件開啟redis服務器

# MAC/Linux
$ pwd
/Users/hqs/redis-5.0.2
$ src/redis-server redis.conf 

# windows
$ redis-server.exe redis-windows.conf

(2)執行爬蟲文件

$ pwd
/Users/hqs/ScrapyProjects/wangyiPro/wangyiPro/spiders
$ scrapy runspider wangyi.py

(3)在redis客戶端中,將起始url扔到調度器隊列

$ src/redis-cli 
127.0.0.1:6379> lpush wangyi https://news.163.com
(integer) 1
127.0.0.1:6379> keys *
1) "data"
2) "qiubai:items"
3) "name"
4) "qiubai:dupefilter"
5) "wangyi:items"
127.0.0.1:6379> lrange wangyi:items 0 -1   # 從頭到尾查看數據值

  提交起始url后,爬蟲開始干活:

接收到請求

六、github

wangyiPro


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM