项目解决方案评审
获取“网络爬虫”项目所有组件的解决方案,并附详细说明。
解决方案:将URL添加到队列
在此组件中,你需要创建一个 celery 队列,并将任务添加到队列中,以便后续由 worker 获取并处理。
以下是解决方案:
点击 运行 按钮以执行下方提供的解决方案代码。
No configuration found for ID: 9ea795a041540b0b99552f53268cff4fd7c58b0f60db95ee8a970179e355dcf4
解决方案说明
该组件的解决方案可分为三个部分:
-
在 第 4 至 6 行,创建了一个使用
redis作为后端和消息代理的celery队列。同时通过命令redis-server --daemonize yes在后台启动redis服务。 -
在 第 8 至 15 行,定义了一个
celery任务。这包括任务声明@app.task()和后续的任务函数定义,该函数将由工作进程执行。getURL()函数接收一个 URL 作为参数,使用requests获取该 URL 的内容,将响应的text和status_code存储在一个字典中并返回。 -
从 第 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 --detachcelery -A celery-proj worker -n worker2 --detachcelery -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 异常。