爬虫工作量由小到大的思维转变---<第五十二章 Scrapy 深入理解Scrapy爬虫引擎(3)--如何配置和优化Scrapy引擎>

前言:

继续上一篇:https://hsnd-91.blog.csdn.net/article/details/136971842

本章主要介绍 如何通过配置Scrapy的性能参数和优化爬虫中间件来提高爬虫的运行效率和稳定性。通过调整并发请求的数量、设置请求的延迟时间等参数,可以控制爬虫在不过度压力服务器的同时提高数据抓取速度。同时,通过自定义爬虫中间件和下载器中间件,可以对请求和响应进行处理和优化,如使用缓存、处理重定向、启用压缩等,从而进一步提高爬虫的效率和稳定性。

正文:

1. 配置Scrapy的性能参数:

在Scrapy中,我们可以通过配置一些性能参数来优化爬虫的运行效率。这些参数可以帮助我们控制并发请求的数量、设置请求的延迟等,从而提高爬取数据的速度和效率。

2 并发请求的配置:

并发请求是指同时发送多个请求来并行处理,提高爬虫的效率。Scrapy提供了一些参数来配置并发请求的数量。

2.1 CONCURRENT_REQUESTS_PER_DOMAIN:

这个参数用于设置每个域名同时处理的请求的最大数量。默认值为16。可以根据目标网站的性能和自己的网络环境来调整这个值,以避免对服务器造成过大的负载。

2.2 CONCURRENT_REQUESTS:

这个参数用于设置同时处理的总请求数量。默认值为16。可以根据自己的网络环境和机器性能来调整这个值。

2.3 DOWNLOAD_DELAY:

这个参数用于设置每个请求之间的延迟时间,单位为秒。默认值为0,即不延迟。通过设置延迟可以减轻服务器的负载,并防止被目标网站封禁IP。

2.4 AUTOTHROTTLE_ENABLED:

这个参数用于开启自动限速功能。当开启后,Scrapy会根据服务器的响应速度自动调整请求的频率,从而更好地控制并发请求的数量。

2.5 DOWNLOAD_TIMEOUT:

这个参数用于设置下载超时时间,单位为秒。当某个请求在规定时间内没有完成下载,Scrapy会自动重试或放弃该请求。

通过适当调整并发请求的参数,我们可以在尽量避免对服务器造成负担的同时,提高爬取数据的效率。

2.6 案例:

假设我们要爬取一个有较高抓取速度限制的网站,我们可以设置CONCURRENT_REQUESTSDOWNLOAD_DELAY 的值来控制并发请求的数量和延迟时间。

python 复制代码
# settings.py
CONCURRENT_REQUESTS = 8  # 同时处理的请求数
DOWNLOAD_DELAY = 0.5  # 请求之间的延迟时间

通过设置CONCURRENT_REQUESTS为8,即每次同时处理8个请求,而将DOWNLOAD_DELAY设置为0.5秒,即每个请求之间间隔0.5秒,可以使我们的爬虫在较高的抓取速度限制下不被封禁IP,同时也可以平衡服务器的负载。

3 延迟配置:

延迟配置在Scrapy中起到了控制请求发送速度的作用。通过设置延迟时间,我们可以控制请求之间的间隔,避免对服务器造成过大的负荷,同时也能够防止被目标网站封禁IP。

延迟配置的参数主要是DOWNLOAD_DELAY和RANDOMIZE_DOWNLOAD_DELAY:

3.1 DOWNLOAD_DELAY:

DOWNLOAD_DELAY参数用于设置每个请求之间的延迟时间。默认值为0,即不延迟。我们可以将其设置为一个较小的值,如0.5或1,以减轻服务器的负担。

# settings.py
DOWNLOAD_DELAY = 0.5  # 请求之间的延迟时间为0.5秒

通过设定适当的延迟时间,我们可以控制请求的发送速度,避免对服务器产生过大的请求压力。

3.2 RANDOMIZE_DOWNLOAD_DELAY:

RANDOMIZE_DOWNLOAD_DELAY参数用于随机化延迟时间,以防止目标网站检测到请求的模式。默认情况下为True,即启用随机化延迟时间。如果设置为False,则所有请求之间的延迟时间将保持不变。

# settings.py
RANDOMIZE_DOWNLOAD_DELAY = True  # 随机化延迟时间

通过启用随机化延迟时间,我们可以增加请求的随机性,降低被目标网站检测到的可能性,进一步保护我们的爬取行为。

延迟配置可以有效地控制请求的发送速度,避免对服务器造成过大的负荷,同时也有助于保护我们的爬虫行为,避免被目标网站封禁IP。

3.3 案例:

假设我们要爬取一个对请求频率有较高限制的网站,我们可以设置DOWNLOAD_DELAY和RANDOMIZE_DOWNLOAD_DELAY的值来控制请求的发送速度以及增加请求的随机性。

# settings.py
DOWNLOAD_DELAY = 1  # 请求之间的延迟时间为1秒
RANDOMIZE_DOWNLOAD_DELAY = True  # 随机化延迟时间

通过设置下载延迟为1秒,以及随机化延迟时间,我们可以在符合网站要求的前提下,增加爬虫的抓取随机性,提高爬取效率。

以上是配置Scrapy的性能参数中延迟配置的介绍,通过合理设置延迟参数,可以在不过度压力服务器的同时,有效提高爬虫的效率和稳定性。

4 爬虫中间件和下载器中间件的作用:

4.1 爬虫中间件(Spider Middleware)的作用:

爬虫中间件是Scrapy框架中的一个组件,位于Scrapy引擎和爬虫之间。它主要用于对发出的请求和返回的响应进行处理和调整。爬虫中间件的作用包括:

  • 定制化请求:可以修改发出的请求,如修改请求头、添加代理等。
  • 管理Cookie:可以在请求发送前、响应处理前后管理Cookie的过程。
  • 处理重定向:可以在请求遇到重定向时进行处理。
  • 进行请求过滤:可以对请求进行过滤操作,如基于URL、域名、请求头等进行过滤。
  • 实施动态代理:可以在请求发送前后切换不同的代理,提高爬虫的反反爬效果。

通过编写自定义的爬虫中间件,我们可以对请求进行灵活的处理和管理,提高爬虫的可扩展性和适应性。

4.2 下载器中间件(Downloader Middleware)的作用:

下载器中间件是Scrapy框架中的另一个组件,位于Scrapy引擎和下载器之间。它主要用于处理和修改下载请求和响应,以及对下载过程进行干预和控制。下载器中间件的作用包括:

  • 修改请求:可以修改请求的URL、请求头、请求体等信息。
  • 预处理响应:可以在响应返回前对响应进行处理,如解密、解压缩等。
  • 提供代理支持:可以配置代理,实现IP轮换或反反爬虫。
  • 实施缓存策略:可以对请求和响应进行缓存,减少重复请求。
  • 处理异常情况:可以捕获和处理下载过程中的异常,如网络连接错误、超时等。

通过编写自定义的下载器中间件,我们可以对下载过程进行更加细粒度的控制和优化,提高爬虫的稳定性和效率。

5. 优化技巧和策略:

5.1 优化爬虫中间件:

  • 使用缓存:在爬虫中间件中引入缓存机制,可以避免重复请求,减少对服务器的压力。
  • 合理处理重定向:通过爬虫中间件,我们可以在发生重定向时进行自定义处理,如跟踪重定向链接或忽略重定向等。
  • 动态代理切换:通过爬虫中间件,我们可以实现动态代理的切换,绕过反爬虫机制,提高爬虫的稳定性和可用性。

5.2 优化下载器中间件:

  • 启用压缩:在下载器中间件中启用响应压缩功能,可以减少网络传输的流量和请求的响应时间。
  • 引入下载器缓存:通过下载器中间件,我们可以引入缓存机制,避免对相同URL的重复下载,提高爬虫的效率。
  • 引入智能代理:通过下载器中间件,我们可以引入智能代理池,根据请求的特性选择合适的代理,提高爬虫的反反爬能力。

5.3 案例:

假设我们要爬取一个评论网站的信息,而该网站对请求频率有限制,并且对IP的访问次数也有限制,我们可以使用爬虫中间件和下载器中间件来进行优化。

  1. 爬虫中间件的优化案例: 我们可以编写一个自定义的爬虫中间件,实现动态代理切换。通过检测请求失败、被封IP等情况,在爬虫中间件中切换不同的代理,使得每个请求使用不同的IP发送。这样可以绕过目标网站的访问限制,提高爬虫的可用性。

  2. 下载器中间件的优化案例: 我们可以编写一个自定义的下载器中间件,引入缓存机制。在下载器中间件中维护一个已经请求过的URL的缓存,如果下次遇到相同的URL请求,就直接从缓存中获取响应,避免重复下载,提高爬虫的效率。

5.3.2 .1 深究案例

当涉及到下载器中间件的优化案例,引入缓存机制是一个常见而有效的方案。下面是一个基于Scrapy框架的自定义下载器中间件的优化案例代码。

python 复制代码
from scrapy.http import HtmlResponse
from scrapy.utils.python import to_bytes

class CustomDownloaderMiddleware(object):
    def __init__(self):
        self.url_cache = {}

    @classmethod
    def from_crawler(cls, crawler):
        return cls()

    def process_request(self, request, spider):
        if request.url in self.url_cache:
            # 从缓存中直接获取响应
            response = self.url_cache[request.url]
            return HtmlResponse(url=request.url, body=response, request=request, encoding='utf-8')

    def process_response(self, request, response, spider):
        if response.status < 400:
            # 将响应内容保存到缓存中
            self.url_cache[request.url] = to_bytes(response.body)
        return response

我们创建了一个自定义的下载器中间件 CustomDownloaderMiddleware。在 process_request 方法中,我们首先检查当前请求的URL是否已经存在于缓存中,如果是则直接从缓存中获取响应内容并返回一个被解析为 HtmlResponse 对象的响应。这样可以避免重复下载该URL,并提高爬虫的效率。

在 process_response 方法中,我们将成功的响应内容保存到缓存中,以便下次请求时使用。这样可以避免重复下载相同的URL。

要在Scrapy爬虫中应用这个自定义的下载器中间件,需要在 settings.py 配置文件中进行相应的设置。在设置文件中添加如下代码:

python 复制代码
DOWNLOADER_MIDDLEWARES = {
    'your_project_name.middlewares.CustomDownloaderMiddleware': 543,
}

通过引入缓存机制的下载器中间件,可以避免重复下载相同的URL,提高爬虫的效率和速度。同时,这个案例代码可以根据实际需求进行自定义和扩展,以满足不同的优化要求。

通过以上的优化技巧和策略,我们可以提升爬虫的性能和稳定性,在面对限制和反爬措施时更加灵活地进行处理,同时减轻服务器和网络的负载,提高爬虫的效率和可用性。

6.高级应用的一个小案例

当爬虫关闭时发送信息通知的信号扩展可以通过使用Scrapy的信号机制来实现。

案例:

如何在爬虫关闭时发送通知

python 复制代码
import scrapy
from scrapy import signals
from scrapy.mail import MailSender

class NotificationExtension:
    def __init__(self, mail_sender):
        self.mail_sender = mail_sender

    @classmethod
    def from_crawler(cls, crawler):
        extension = cls(mail_sender=crawler.settings.get('MAIL_SENDER'))
        crawler.signals.connect(extension.spider_closed, signal=signals.spider_closed)
        return extension

    def spider_closed(self, spider, reason):
        message = f"The spider '{spider.name}' has been closed. Reason: {reason}"
        self.send_notification(message)

    def send_notification(self, message):
        subject = "Spider Notification"
        recipients = ["your_email@example.com"]  # 修改为接收通知的电子邮件地址
        body = message
        self.mail_sender.send(to=recipients, subject=subject, body=body)

class MySpider(scrapy.Spider):
    name = "example"
    start_urls = ['http://www.example.com']

    def __init__(self):
        self.mail_sender = MailSender()

    def spider_closed(self, reason):
        pass  # 这个方法空着即可

    def start_requests(self):
        yield scrapy.Request(url=self.start_urls[0], callback=self.parse)

    def parse(self, response):
        pass

# settings.py的相应配置
MAIL_SENDER = {
    "MAIL_FROM": "your_email@example.com",  # 发件人邮箱
    "MAIL_HOST": "your_smtp_host",  # SMTP服务器主机
    "MAIL_PORT": 587,  # SMTP服务器端口
    "MAIL_USER": "your_username",  # SMTP服务器用户名
    "MAIL_PASS": "your_password",  # SMTP服务器密码
    "MAIL_TLS": True,  # 是否使用TLS
}

EXTENSIONS = {
    'myproject.extensions.NotificationExtension': 500,
}

NotificationExtension类继承自Scrapy的信号扩展类,通过实现spider_closed方法,在爬虫关闭时触发信号。然后,在该方法中调用send_notification方法发送通知。

send_notification方法使用MailSender来发送邮件通知,配置发送方和接收方的相关信息。

MySpider爬虫中,定义了一个空的spider_closed方法,这是为了使信号扩展能够触发。

确保将相关配置添加到settings.py文件中,包括发件人、SMTP服务器等配置。

PS:为了发送邮件通知,确保Scrapy及相关依赖已正确安装,您可能需要安装Twisted和pyOpenSSL模块,以及邮件发送所需的SMTP库(如smtplib)。

总结:

主要讲配置Scrapy的性能参数和优化爬虫中间件的方法。通过合理调整并发请求的数量、设置请求的延迟时间等参数,可以提高爬虫的效率和稳定性。同时,通过自定义爬虫中间件和下载器中间件,可以对请求和响应进行处理和优化,如使用缓存、处理重定向、启用压缩等,进一步提升爬虫的性能和可用性。以上方法和技巧可以帮助爬虫在应对限制和反爬措施时更加灵活,同时减轻服务器和网络的负载,提高数据的抓取效率和质量。

相关推荐
亿牛云爬虫专家6 小时前
捕获抖音截图:如何用Puppeteer保存页面状态
爬虫·爬虫代理·puppeteer·抖音·亿牛云·代理ip·douyin
亿牛云爬虫专家6 小时前
Puppeteer教程:使用CSS选择器点击和爬取动态数据
javascript·css·爬虫·爬虫代理·puppeteer·代理ip
明月清风徐徐7 小时前
Scrapy爬取豆瓣电影Top250排行榜
python·selenium·scrapy
abments8 小时前
JavaScript逆向爬虫教程-------基础篇之常用的编码与加密介绍(python和js实现)
javascript·爬虫·python
小白学大数据14 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
数据小小爬虫15 小时前
如何用Java爬虫“偷窥”淘宝商品类目API的返回值
java·爬虫·php
B站计算机毕业设计超人20 小时前
计算机毕业设计Python+大模型农产品价格预测 ARIMA自回归模型 农产品可视化 农产品爬虫 机器学习 深度学习 大数据毕业设计 Django Flask
大数据·爬虫·python·深度学习·机器学习·课程设计·数据可视化
single_ffish20 小时前
XPath:网络爬虫中的数据提取利器
爬虫·python
abments1 天前
JavaScript逆向爬虫教程-------基础篇之JavaScript密码学以及CryptoJS各种常用算法的实现
javascript·爬虫·密码学
小爬虫程序猿1 天前
python爬虫获得淘宝商品类目 API 返回值说明
开发语言·爬虫·python