scrapy+CrawlSpider、全栈式,分布式,增量式

本篇博客介绍了如何使用Python的Scrapy框架构建全栈爬虫,包括CrawlSpider的使用,设置规则抓取网页数据,并详细解析了分布式爬虫的实现,利用scrapy-redis进行任务调度和去重。同时,展示了增量式爬虫的实现方式,通过数据指纹判断网站内容更新,确保只抓取新数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

全栈爬虫

CrawlSpider全栈爬取的一个类

创建项目后创建爬虫文件:scrapy genspider-t crawl spiderName www.xxx.com

当前文件:D:\python_test\scrapyProject\crawl_spider\crawl_spider\spiders\spider_all.py

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import CrawlSpiderItem

class SpiderAllSpider(CrawlSpider):
    name = 'spider_all'

    start_urls = ['https://sc.chinaz.com/jianli/free.html']
    # allow带正则表达,表示提取当前响应数据满足该正则的url
    link = LinkExtractor(allow=r'/jianli/free_\d+\.html')
    # link_detail = LinkExtractor(allow=r'/jianli/free_\d+\.html')
    rules = (
        # Rule对匹配到的link数据发起请求,然后使用callback调用函数进行解析
        # follow=True表示把每一个请求当做首页来处理,一般在页码可以使用到,不需要则不填该参数
        # 可填写多个规则进行匹配,但两个Rule是无法直接使用item进行关联的,因此如果想有item关联,还是使用原来的方法
        Rule(link, callback='parse_item', follow=False),
        # Rule(link_detail, callback='detail_item'),
    )


    def parse_item(self, response):
        div_list = response.xpath('//*[@id="container"]/div')
        for div in div_list:
            title =  div.xpath('./p/a/text()').extract_first()
            detail_url = "https:"+div.xpath('./p/a/@href').extract_first()
            item=CrawlSpiderItem()
            item['title']=title
            yield scrapy.Request(url=detail_url,
                                 callback=self.detail_parse,
                                 meta={'item':item})

        return item

    def detail_parse(self,response):
        item = response.meta['item']
        downloadurl=response.xpath('//*[@id="down"]/div[2]/ul/li[2]/a/@href').extract_first()
        item['url']=downloadurl
        return item

分布式爬虫

创建基于crawlSpider的爬虫文件

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider
from ..items import FbsproItem
class FbsSpider(RedisCrawlSpider): # 导入父类
    name = 'fenbushi'
    
    redis_key = 'queue' # redis_key表示调度器队列的名称,用来替换start_url,以下就是常规解析操作

    rules = (
        #提取所有的页码链接,且对其进行请求发送
        Rule(LinkExtractor(allow=r'id=1&page=\d+'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        li_list = response.xpath('/html/body/div[2]/div[3]/ul[2]/li')
        for li in li_list:
            title = li.xpath('./span[3]/a/text()').extract_first()
            statu = li.xpath('./span[2]/text()').extract_first()
            item = FbsproItem()
            item['title'] = title
            item['status'] = status
            yield item

# 修改setting文件
# 所有电脑都执行同一套代码后,在暂停的时候在redis工具输入命令 lpush queue https://mp.youkuaiyun.com/mp_blog/(即起始url)

 修改setting文件

1、常规内容修改(robots和ua等)

2、指定可以被共享的管道类
ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 400}

3、指定可以被共享的调度器
# 使用scrapy-redis组件的去重队列
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 是否允许暂停,当程序中止后重新运行,可以在停止位置继续执行
SCHEDULER_PERSIST = True

4、指定数据库
REDIS_HOST = '指定redis的ip'
REDIS_PORT = 6379

连续本地的话,修改redis数据库的配置文件(redis.windows.conf)

bind 127.0.0.1
#将上述代码注释即可(解除本机绑定,实现外部设备访问本机数据库)

如果配置文件中还存在:protected-mode = true,将true修改为false,
修改为false后表示redis数据库关闭了保护模式,表示其他设备可以远程访问且修改你数据库中的数据

最后,所有电脑都执行同一套代码后,在暂停的时候在redis工具输入命令 lpush queue https://mp.youkuaiyun.com/mp_blog/(即起始url)

增量式爬虫

用来监测网站数据更新的情况,爬取网站最新更新出来的数据。

数据指纹:数据的唯一标识。
import scrapy
import redis
from ..items import Zlsdemo1ProItem
class DuanziSpider(scrapy.Spider):
    name = 'duanzi'
    start_urls = ['https://ishuo.cn/']
    #Redis的链接对象
    conn = redis.Redis(host='127.0.0.1',port=6379)

    def parse(self, response):
        li_list = response.xpath('//*[@id="list"]/ul/li')
        for li in li_list:
            content = li.xpath('./div[1]/text()').extract_first()
            title = li.xpath('./div[2]/a/text()').extract_first()
            all_data = title+content
            #生成该数据的数据指纹
            import hashlib  # 导入一个生成数据指纹的模块
            m = hashlib.md5()
            m.update(all_data.encode('utf-8'))
            data_id = m.hexdigest()

            ex = self.conn.sadd('data_id',data_id)
            if ex == 1:#sadd执行成功(数据指纹在set集合中不存在)
                print('有最新数据的更新')
                item = Zlsdemo1ProItem()
                item['title'] = title
                item['content'] = content
                yield item
            else:#sadd没有执行成功(数据指纹在set集合中存储)
                print('暂无最新数据更新')
使用详情页的url充当数据指纹

import scrapy
import redis
from ..items import Zlsdemo2ProItem
class JianliSpider(scrapy.Spider):
    name = 'jianli'
    start_urls = ['https://sc.chinaz.com/jianli/free.html']
    conn = redis.Redis(host='127.0.0.1',port=6379)
    def parse(self, response):
        div_list = response.xpath('//*[@id="container"]/div')
        for div in div_list:
            title = div.xpath('./p/a/text()').extract_first()
            #充当数据指纹
            detail_url = 'https:'+div.xpath('./p/a/@href').extract_first()
            ex = self.conn.sadd('data_id',detail_url)
            item = Zlsdemo2ProItem()
            item['title'] = title
            if ex == 1:
                print('有最新数据的更新')
                yield scrapy.Request(url=detail_url,callback=self.parse_detail,meta={'item':item})
            else:
                print('暂无数据更新')

    def parse_detail(self,response):
        item = response.meta['item']
        download_url = response.xpath('//*[@id="down"]/div[2]/ul/li[1]/a/@href').extract_first()
        item['download_url'] = download_url

        yield item

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑*杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值