scrapy使用redis實現增量式爬取


增量式爬蟲


監測網站數據更新的情況,只會爬取網站最新更新出來的數據。


需求:

爬取某個電影網站,然后把電影的名稱和簡介進行持久化存儲

實現思路

指定一個起始url


基於CrawISpider獲取其他頁碼鏈接

基於Rule將其他頁碼鏈接進行請求


從每一個頁碼對應的頁面源碼中解析出每一個電影詳情頁的URL,然后解析出電影的名稱和簡介進行持久化存儲

實現增量式核心內容:

使用redis sets檢測電影詳情頁的url之前有沒有請求過


將未爬取過的url頁的
詳情頁的url發起請求,

實現代碼

創建工程

scrapy startproject  moviePro

cd moviePro
scrapy genspider -t crawl movie www.xxx.com

spider文件

# -*- coding: utf-8 -*-
import scrapy
from redis import Redis
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from moviePro.items import MovieproItem
import sys

class MovieSpider(CrawlSpider):
    name = 'movie'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://www.4567kan.com/frim/index1.html']
    # 得到默認編碼
    print(sys.getdefaultencoding())
    # 連接redis
    conn = Redis(host='127.0.0.1', encoding='utf-8', port=6379)
    print(conn)

    rules = (
        Rule(LinkExtractor(allow=r'/frim/index1-\d+\.html'), callback='parse_item', follow=True),
        # 獲取頁碼對應的url
    )

    def parse_item(self, response):
        print(response)
        li_list = response.xpath('//ul[@class="stui-vodlist clearfix"]/li')
        for li_item in li_list:
            title = li_item.xpath('./div[@class="stui-vodlist__box"]/div[1]/h4/a/text()').extract_first()
            # 標題
            new_url = 'https://www.4567kan.com/'+li_item.xpath('./div[@class="stui-vodlist__box"]/div[1]/h4/a/@href').extract_first()
            # url
            # 將url存入redis的set集合中
            item = MovieproItem()
            item['name'] = title
            ex = self.conn.sadd('urls',new_url)
            # print(title)
            # print(new_url)
            if ex==1:
                print("該url沒有被爬取過,可以進行數據爬取")
                yield scrapy.http.Request(url=new_url, callback=self.parse_detail, meta={'item':item})
            else:
                print("數據沒有進行更新,沒有數據爬取")

    def parse_detail(self, response):

        # 簡介
        desc = response.xpath('//div[@class="stui-content__detail"]/p[5]/span[2]/text()').extract()
        item = response.meta['item']
        item['desc']=''.join(desc).strip()
        # print(desc)

        yield item

Pipeline文件

from redis import Redis
class MovieproPipeline(object):
    conn = None
    def open_spider(self,spider):
        self.conn = spider.conn
    def process_item(self, item, spider):
        dic = {
            'name':item['name'],
            'desc':item['desc']
        }
        print(dic)
        self.conn.lpush('movieData',dic)
        return item

 

items文件

import scrapy


class MovieproItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name = scrapy.Field()
    desc = scrapy.Field()
    pass

 

運行

scrapy crawl movie

該url沒有被爬取過,可以進行數據爬取
……

{'name': '游戲改變者2015', 'desc': '丹尼爾·雷德克里夫有望加盟一部關於《俠盜獵車手》創始人的BBC電視電影,雙方正在談判中丹尼爾將出演山姆·豪澤是Rockstar公司的總裁,他一手推出了《俠盜獵車手》、《馬克·佩恩
》等熱門游戲,影片將圍'}
['象人(約翰•赫特 John Hurt 飾)是一個天生的畸形症患者,他的臉長得就像大象的臉,因此而得名象人一直被利欲昏心的馬戲團老板利用,帶到世界各地去巡回演出,受盡了非人的虐待。象人所經受的遭遇社會名']
{'name': '象人', 'desc': '象人(約翰•赫特 John Hurt 飾)是一個天生的畸形症患者,他的臉長得就像大象的臉,因此而得名象人一直被利欲昏心的馬戲團老板利用,帶到世界各地去巡回演出,受盡了非人的虐待。象人所經受
的遭遇社會名'}


……

 

 

 

解決redis中文顯示亂碼

第一步,打開命令窗口,如果我們要修改成UTF8編碼,輸入命令

CHCP 65001

 

 查看驗證

 

 設置字體

 

 登錄redis客戶端

C:\redis64>redis-cli --raw
127.0.0.1:6379> keys *
fbs:items
age
names
urls
fbs:requests
movieData
fbs:dupefilter
name
127.0.0.1:6379> lrange movieData 0 2
{'name': '飛虎', 'desc': '米妮(梁詠琪 飾)是海關督察,近日里,她獲得消息,得知大量毒品即將抵達香港,於是決心調查此案,然而卻遭到了毒販
冰后”強大的火力抵抗,敗下陣來飛虎隊隊長王東(王敏德 飾)帶領隊員們進駐海關,王東更是坦'}
{'name': '惡魔灣', 'desc': 'An interracial lesbian couple commit a murder and have
to flee for their lives.'}
{'name': '象人', 'desc': '象人(約翰•赫特 John Hurt 飾)是一個天生的畸形症患者,他的臉長得就像大象的臉,因此而得名象人一直被
欲昏心的馬戲團老板利用,帶到世界各地去巡回演出,受盡了非人的虐待。象人所經受的遭遇社會名'}
127.0.0.1:6379>

 


免責聲明!

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



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