Scrapy之CrawlSpider(Python)

关于CrawlSpider

        CrawlSpider 是Scrapy框架中的一个爬虫类,用于快速开发和部署基于规则的爬虫。

CrawlSpider 继承自Scrapy的Spider类,但与普通的Spider类不同,CrawlSpider可以根据一些规则自动发现和跟踪链接,从而实现深度爬取。

CrawlSpider的特点包括:

  1. 自动跟踪链接:CrawlSpider可以根据指定的规则自动发现和跟踪链接,无需手动定义start_requests()方法。

  2. 规则定义:CrawlSpider使用rules属性来定义规则,规则可以包括允许和禁止的URL模式、回调函数等。

  3. 多层爬取:CrawlSpider可以实现多层级的爬取,通过设置规则的深度限制,可以控制爬取的层级。

  4. 提取链接和数据:CrawlSpider可以通过LinkExtractor提取链接,并自动调用指定的回调函数处理提取到的数据。

使用CrawlSpider可以很方便地实现爬虫的配置和开发,提高爬取效率和准确性。

CrawlSpider创建

要创建crawlspider,首先需要安装Scrapy。以下是crawlspider的安装教程:

  1. 确保已安装Python和pip。

  2. 打开命令提示符或终端。

  3. 使用以下命令安装Scrapy:

    pip install scrapy
    

  4. 安装完成后,可以使用以下命令检查是否安装成功:

    scrapy version
    

    如果成功安装,会显示Scrapy的版本号。

  5. 创建新的Scrapy项目。在命令提示符或终端中,使用以下命令创建一个名为"myproject"的新项目:

    scrapy startproject myproject
    

    这将在当前目录下创建一个名为"myproject"的文件夹,并且包含一个默认的Scrapy项目结构。

  6. 进入新创建的项目目录:

    cd myproject
    

  7. 创建一个新的crawlspider:

    scrapy genspider  -t crwal myspider example.com
    

    这将在项目中创建一个名为"myspider"的crawlspider,以"example.com"作为起始URL。

  8. CrawlSpider是Scrapy框架中的一个类,它提供了一种更便捷的方式来构建一个可以爬取多个网站的爬虫。

    import scrapy
    from scrapy.spiders import CrawlSpider, Rule
    from scrapy.linkextractors import LinkExtractor
    
    class MySpider(CrawlSpider):
        name = 'example'
        allowed_domains = ['example.com']
        start_urls = ['http://www.example.com']
    

    接下来,定义规则(Rule)来指定爬取的链接和对应的处理方法。规则是一个Rule对象的列表,每个规则都包含一个LinkExtractor和一个callback函数。

    rules = (
        Rule(
            LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', )),
            callback='parse_category',
            follow=True
        ),
    )
    

    在这个例子中,用LinkExtractor来定义某个链接的匹配规则,其中allow表示允许的链接pattern,deny表示不允许的链接pattern。callback指定了对应链接的处理函数。follow=True表示是否继续跟进从这个链接提取到的链接。

    最后,在Spider中实现处理函数。

    def parse_category(self, response):
        self.logger.info('Visited %s', response.url)
        # 在这里处理response,如提取信息、存储数据等
    

    在这个例子中,parse_category函数用于处理符合规则的链接,可以在这个函数中提取需要的信息,存储数据等。

    最后,在命令行中运行爬虫:

    scrapy crawl example
    

    以上就是使用CrawlSpider的基本教程。通过使用CrawlSpider,你可以更便捷地构建一个可以爬取多个网站的爬虫,并且通过定义规则来指定爬取的链接和对应的处理方法。

具体应用 

        使用其框架,对每个页面中的每个新闻问政标题里边的详细内容进行多层爬取

        

首先start_url列表中填入所爬取的网址,在LinkExtrator中,写入一段正则表达式,表达式根据分页url规律所编写

class SixSpider(CrawlSpider):
    name = "six"
    # allowed_domains = ["www.baidu.com"]
    start_urls = ["https://wz.sun0769.com/political/index/politicsNewest?id=1&page=1"]

    # 链接提取器,allow=“正则表达式”
    # 作用:根据指定的规则进行指定链接的提取
    link=LinkExtractor(allow=r"id=1&page=\d+")
    rules = (
        # 规则解析器
        # 作用:根据链接提取器提取的的链接按照指定的规则去进行解析操作
        Rule(link, callback="parse_item", follow=False),
    #     follow=false是进行局部的链接提取
    #     follow=true则将链接提取器 继续作用到 链接提取器提取的链接 所对应的页面
    )

   这边的follow选项我建议学习测试的话,建议选择False,进行一个分页的局部爬取,开启True的话,会把每个分页的所有内容进行爬取,这会触发网站对其的爬虫检测,封锁IP了,一开始就不建议开启了

 # 解析新闻标题
    def parse_item(self, response):
        tr_list=response.xpath('/html/body/div[2]/div[3]/ul[2]/li')

        for tr in tr_list:
            new_title=tr.xpath('./span[3]/a/text()').extract_first()
            print(new_title)
            new_url=tr.xpath('./span[3]/a/@href').extract_first()
            new_url="https://wz.sun0769.com"+str(new_url)
            item=SixbloodItem()
            item['new_title']=new_title
            yield scrapy.Request(url=new_url,callback=self.parse_detail,meta={'item':item},dont_filter=True)

在回调方法中,就可以对于当前分页的标题和其详情页的URL进行爬取,创建一个item对象,将爬取的值储存到其中,在通过请求传参,实现多层爬取,其实也能将详情页的URL放入链接提取器中,此次案例就不再使用了

# 解析新闻内容
    def parse_detail(self, response):
        # extract():这个方法返回的是一个数组list,,里面包含了多个string,如果只有一个string,则返回['ABC']这样的形式。
        # extract_first():这个方法返回的是一个string字符串,是list数组里面的第一个字符串。
        new_detail=response.xpath('/html/body/div[3]/div[2]/div[2]/div[2]/pre/text()').extract()
        # 将列表内容转换为字符串
        new_detail=" ".join(new_detail)
        # 消除里边的空格和换行符
        new_detail=new_detail.replace('\n', '').replace('\r', '')

        # 储存到item中去
        item=response.meta['item']
        item['new_detail']=new_detail

        # 最终将所有response存储到item中,由item提交到管道类中去
        yield item

        在管道类中进行持久化的储存

from itemadapter import ItemAdapter


class SixbloodPipeline:
    fp = None

    # 对爬取的数据进行储存
    # 重写一个父类的方法:该方法只会在开始爬虫的时候执行一次
    def open_spider(self, spider):
        print("开始爬虫》》》》")
        # 保存在当前文件WyNews.txt中
        self.fp = open('./CzNet.txt', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        new_title = item['new_title']
        new_detail = item['new_detail']
        print(new_title)
        self.fp.write(new_title + ':' + new_detail + '\n')

        # 传递给下一个即将被执行的管道类
        return item

    def close_spider(self, spider):
        print("结束爬虫》》》》")
        self.fp.close()

        打开管道类

        爬取前的Setting.py文件基本设置

ROBOTSTXT_OBEY = False

LOG_LEVEL='ERROR'

USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"

        item.py文件设置

import scrapy

class SixbloodItem(scrapy.Item):
    new_title=scrapy.Field()
    new_detail=scrapy.Field()
    pass

        运行文件全部完整代码

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from sixBlood.items import SixbloodItem

class SixSpider(CrawlSpider):
    name = "six"
    # allowed_domains = ["www.baidu.com"]
    start_urls = ["https://wz.sun0769.com/political/index/politicsNewest?id=1&page=1"]

    # 链接提取器,allow=“正则表达式”
    # 作用:根据指定的规则进行指定链接的提取
    link=LinkExtractor(allow=r"id=1&page=\d+")
    rules = (
        # 规则解析器
        # 作用:根据链接提取器提取的的链接按照指定的规则去进行解析操作
        Rule(link, callback="parse_item", follow=True),
    #     follow=false是进行局部的链接提取
    #     follow=true则将链接提取器 继续作用到 链接提取器提取的链接 所对应的页面
    )

    # 解析新闻标题
    def parse_item(self, response):
        tr_list=response.xpath('/html/body/div[2]/div[3]/ul[2]/li')

        for tr in tr_list:
            new_title=tr.xpath('./span[3]/a/text()').extract_first()
            print(new_title)
            new_url=tr.xpath('./span[3]/a/@href').extract_first()
            new_url="https://wz.sun0769.com"+str(new_url)
            item=SixbloodItem()
            item['new_title']=new_title
            yield scrapy.Request(url=new_url,callback=self.parse_detail,meta={'item':item},dont_filter=True)

    # 解析新闻内容
    def parse_detail(self, response):
        # extract():这个方法返回的是一个数组list,,里面包含了多个string,如果只有一个string,则返回['ABC']这样的形式。
        # extract_first():这个方法返回的是一个string字符串,是list数组里面的第一个字符串。
        new_detail=response.xpath('/html/body/div[3]/div[2]/div[2]/div[2]/pre/text()').extract()
        # 将列表内容转换为字符串
        new_detail=" ".join(new_detail)
        # 消除里边的空格和换行符
        new_detail=new_detail.replace('\n', '').replace('\r', '')

        # 储存到item中去
        item=response.meta['item']
        item['new_detail']=new_detail

        # 最终将所有response存储到item中,由item提交到管道类中去
        yield item

        最终项目的命令行输入scrapy crawl 项目名,完成爬取

  • 30
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值