ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

增量式爬虫

2019-05-27 19:41:38  阅读:186  来源: 互联网

标签:color 爬虫 content fa 增量 btn border before


 

<style></style> <style></style> <style></style> <style></style> <style></style>

 

 

增量式爬虫

 

需求: 定时 更新程序 以便爬取网站中最近更新的数据

 

一、增量式爬虫

 
  • 概念: 通过爬虫程序检测某网站数据更新的情况,以便可以爬取到该网站更新出的新数据
  • 如何进行增量式的爬取工作:
    • 在发送请求之前判断 此 URL 是不是之前爬过
    • 在解析内容之后判断 这部分内容 之前是否爬过
    • 在写入 存储介质时 判断 内容是不是已经在介质中存在
 
  • 分析: 不难发现,其实增量式爬取的核心是 去重 ,至于说去重的操作在哪个步骤起作用,只能说各有利弊,在我看来, 前两种思路需要根据实际情况取一个(也可能都用)。
    • 第一种思路适合有不断新页面的出现,比如说小说的新章节,每天的最新新闻等等;
    • 第二种思路则适合页面内容会不断更新的网站。
    • 第三种思路是相当于最后一道防线。这样做可以最大程度上达到去重的目的。
 

去重方法:

 
  • 思路: 通过已有的机制达到去重的目的 1、redis的 set集合。 2、python 的 set 集合
  • 我们选择 redis 的 set 集合, 以求最大效率。
  • 将爬取过程中产生的 URL 进行存储,存储在 redis 的 set 中,
    • 根据 Redis.sadd(key,value) 的返回结果判断此 URL 是否已爬取过,
    • 1 表示存在,则发起请求; 0 表示不存在,则不进行请求。
  • 对爬取到的 网页内容进行唯一标识的制定, 然后将该唯一标识存储在 redis 的 set 中,当下次爬取到网页数据内容的时候,在进行持久化存储之前, 首先判断一下该 数据的 唯一标识在 redis 的 set 中是否存在,再决定 是否执行入库操作。
 

案例 一、

 

需求:爬取4567tv网站中所有的 电影名 和 作者名

In [ ]:
- 说明 1 、: 项目配置文件 settings.py :
    - 默认配置:
# 添加 UA
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
# 是否遵循爬虫协议 , 不遵从
ROBOTSTXT_OBEY = False
# 开启 scrapy 默认管道 
ITEM_PIPELINES = {
   'increment1_Pro.pipelines.Increment1ProPipeline': 300,
}
- 说明 2、: items.py 文件 自己根据代码编写
 

爬虫文件

In [ ]:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from redis import Redis
from increment1_Pro.items import Increment1ProItem


class MovieSpider(CrawlSpider):
    name = 'movie'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://www.4567tv.tv/index.php/vod/show/class/%E6%81%90%E6%80%96/id/9.html']

    rules = (
        Rule(LinkExtractor(allow=r'/index.php/vod/show/class/%E6%81%90%E6%80%96/id/9/page/\d+\.html'), callback='parse_item', follow=True),
    )
    def parse_item(self, response):
        conn = Redis(host='127.0.0.1',port=6379)

        detail_url_list ='https://www.4567tv.tv' + response.xpath('//li[@class="col-md-6 col-sm-4 col-xs-3"]/div/a/@href')

        for url in detail_url_list:
            # ex 若 为 1 ,表示 为新数据
            ex = conn.sadd('movies_url',url)
            if ex == 1:
                yield  scrapy.Request(url=url,callback=self.self.parse_detail)
            else:
                print("此站<%s>无更新数据,暂无新数据可爬"%url)

    def parse_detail(self,response):
        item = Increment1ProItem()
        item['name'] = response.xpath('//div[@class="stui-content__detail"]/h1/text()').extract_first()
        item['actor'] = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[3]/a/text()').extract_first()

        yield item
 

管道文件:

In [ ]:
# -*- coding: utf-8 -*-
from redis import Redis
class Increment1ProPipeline(object):
    def open_spider(self,spider):
        self.conn=Redis(host='127.0.0.1',port=6379)

    def process_item(self, item, spider):
        # dic = {
        #     'name': item['name'],
        #     'actor': item['actor'],
        # }
        print('正在入库!')
        self.conn.lpush('movie_data',item)
        return item
 

案例 二、

 

需求:爬取糗事百科中的 段子内容 和 作者名。

 

爬虫文件:

In [ ]:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from increment_data.items import IncrementDataItem
from redis import Redis
import hashlib

class QiubaiSpider(CrawlSpider):
    name = 'qiubai'
    # allowed_domains = ['www.xx.com']
    start_urls = ['https://www.qiushibaike.com/text/']

    rules = (
        Rule(LinkExtractor(allow=r'/text/page/\d+/'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        div_list = response.xpath('//div[@class="article block untagged mb15 typs_hot"]')
        conn = Redis(host='127.0.0.1',port=6379)
        for div in div_list:
            item = IncrementDataItem()
            item['author'] = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()
            # item['content'] = response.xpath('./a[1]/div/span/text()').extract_first()
            item['content'] = div.xpath('.//div[@class="content"]/span/text()').extract()
            item['content'] = ''.join(item['content'])
            source = item['author'] + item['content']

            # 自定制 一种形式的 数据指纹, 是数据的唯一标识
            hashValue = hashlib.sha256(source.encode()).hexdigest()

            ex = conn.sadd("qiubai_hash",hashValue)
            if ex == 1:
                yield item
            else:
                print("此数据 已 爬")
                
 

管道文件:

In [ ]:
# -*- coding: utf-8 -*-
from redis import Redis
#####################  注意  ########################
"""
    在这里 向 redis 的列表中 lpush 字典时 ,则python  中 redis 的版本需要为 2.10.6,否则报错
        pip3 install redis==2.10.6
"""
class IncrementDataPipeline(object):
    conn = Redis(host='127.0.0.1', port=6379)
    def process_item(self, item, spider):
        dic = {
            'author': item['author'],
            'content': item['content'],
        }
        self.conn.lpush('qiubai_data',dic)
        print('爬取到一条数据, 正在入库')
        return item
    

标签:color,爬虫,content,fa,增量,btn,border,before
来源: https://www.cnblogs.com/shiwei1930/p/10932618.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有