Logo

项目解决方案评审

获取“网络爬虫”项目所有组件的解决方案,并附详细说明。

概念

项目解决方案评审

获取“网络爬虫”项目所有组件的解决方案,并附详细说明。

解决方案:将URL添加到队列

在此组件中,你需要创建一个 celery 队列,并将任务添加到队列中,以便后续由 worker 获取并处理。

以下是解决方案:

点击 运行 按钮以执行下方提供的解决方案代码。

No configuration found for ID: 9ea795a041540b0b99552f53268cff4fd7c58b0f60db95ee8a970179e355dcf4

解决方案说明

该组件的解决方案可分为三个部分:

  1. 在 第 4 至 6 行,创建了一个使用 redis 作为后端和消息代理的 celery 队列。同时通过命令 redis-server --daemonize yes 在后台启动 redis 服务。

  2. 在 第 8 至 15 行,定义了一个 celery 任务。这包括任务声明 @app.task() 和后续的任务函数定义,该函数将由工作进程执行。getURL() 函数接收一个 URL 作为参数,使用 requests 获取该 URL 的内容,将响应的 text 和 status_code 存储在一个字典中并返回。

  3. 从 第 17 至 25 行 是 main 函数,其中包含一个名为 urls 的列表,用于存放所有需要获取的 URL,以及一个空的 results 列表用于存储所有响应结果。我们向 urls 列表中添加了三个示例 URL。在 第 21 至 22 行,我们遍历这些 URL,使用 getURL.delay() 将其发送到队列,并将返回的 celery.result.AsyncResult 对象添加到 results 列表中。最后,在 第 24 至 25 行,我们显示每个任务的状态,此时状态仍为 pending,因为尚未有工作进程运行。

解决方案:添加工作进程

现在任务已等待在队列中,你可以添加 celery 工作进程来处理这些任务。可以通过命令 celery -A celery-proj worker 添加工作进程。当使用多个工作进程时,还可以通过 -n workername 参数为工作进程命名。使用 --detach 参数可使工作进程在后台运行。

以下是解决方案:

点击 运行 按钮以执行下方提供的解决方案代码。

No configuration found for ID: bf22fcf76bcc5b084fba22884dadeaf6d29f54bd17779ffcebce62c20e96aefc

解决方案说明

我们通过以下三条命令启动三个工作进程:

  • celery -A celery-proj worker -n worker1 --detach
  • celery -A celery-proj worker -n worker2 --detach
  • celery -A celery-proj worker -n worker3 --detach

工作进程开始处理任务,响应结果被存储在 results 列表中。任务状态从 PENDING 变为 SUCCESS。在 第 26 行,通过 result.get() 函数打印出各个任务的返回结果。

解决方案:添加错误处理

我们使用 tenacity 库来处理网络爬虫中的失败情况。

以下是解决方案:

点击 运行 按钮以执行下方提供的解决方案代码。

No configuration found for ID: 147b5fe2392f811a3e4af4b4f68a16aa8a873e6f46ec533b53e92c91fd98b2f5

解决方案说明

tenacity 库被应用在 getURL() 函数中。在 第 21 行,定义了 tenacity 装饰器,其中 wait=tenacity.wait_fixed(5) 表示每次重试前等待 5 秒;stop=tenacity.stop_after_attempt(3) 表示最多尝试 3 次后放弃对某个 URL 的请求。

在 第 22 至 23 行,定义了 do_something_and_retry() 函数,并将其应用装饰器。该函数在定义后立即被调用。原 getURL() 函数的主体逻辑被移至 第 9 至 17 行 定义的 do_something() 函数中。do_something() 的返回结果传递给 do_something_and_retry(),再由其返回给 getURL(),最终返回给 main 函数(即 results 列表)。

为了演示重试机制,我们将 urls 列表中的第三个 URL 替换为一个不存在的地址(http://example2ed3d.com)。当 requests 尝试获取该 URL 时,会在 第 12 行 检查响应状态码。由于该 URL 返回的状态码不是 200,因此会抛出 RuntimeError 异常。tenacity 会持续重试,但最终在三次尝试失败后抛出 tenacity.RetryError 异常。

CPU 扩展

事件循环