django celery 异步任务 异步存储

news2024/11/28 14:51:29

环境:win11、python 3.9.2、django 4.2.11、celery 4.4.7、MySQL 8.1、redis 3.0

背景:基于django框架的大量任务实现,并且需要保存数据库

时间:20240409

说明:异步爬取小说,并将其保存到数据库

1、创建django项目,并创建app,测试调通

# 创建目录GetFiction
pip install django==4.2.11 pymysql-1.1.0
django-admin startproject getfiction .
django-admin startapp getsection

配置MySQL连接、应用注册、日志、其他配置

# getfiction/__init__.py  filepath

import pymysql

pymysql.install_as_MySQLdb()

# getfiction/settings.py  filepath

# 数据库连接

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'fictions',
        'USER': '****',
        'PASSWORD': '****',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

# 应用注册

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'getsection',
]

# 其他配置

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'

# 日志配置

import logging

# 创建日志器
logger = logging.getLogger("test")
# 为日志器设置日志等级,如果这里不设置,将会使用其父级日志器的等日志等级
# 这里它的父日志器是root,root的默认日志级别是 logging.WARNING
logger.setLevel(logging.INFO)

# 创建文件处理程序
fh = logging.FileHandler(filename="./test.log",encoding="utf8")
# 创建流处理程序
sh = logging.StreamHandler()

# 为文件处理程序设置日志等级
fh.setLevel(logging.ERROR)
# 为流处理程序设置日志等级
sh.setLevel(logging.DEBUG)

# 创建格式化程序
ffmt = logging.Formatter(
    fmt = "%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s",
    datefmt = "%Y/%m/%d %H:%M:%S"
)
# 创建格式化程序
sfmt = logging.Formatter(
    fmt = "%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d - %(message)s",
)

# 将 ffmt 格式化程序应用到 fh 文件处理程序
fh.setFormatter(ffmt)
# 将 sfmt 格式化程序应用到 sh 流处理程序
sh.setFormatter(sfmt)

# 将文件处理程序应用到logger日志器
logger.addHandler(fh)
# 将流处理程序应用到logger日志器
logger.addHandler(sh)

 配置首页的路由以及视图函数

# getfiction/urls.py

from getsection.views import index

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index),
]

# getsection/views.py

from django.shortcuts import HttpResponse

def index(request):
    # 测试首页
    return HttpResponse(str("hello"))

调试(postman或是浏览器都行)

python manage.py runserver 0.0.0.0:8000

postman测试结果,如下:

2、django中集成celery,异步处理任务,并将任务存储到MySQL

celery配置:broker使用redis,backend使用django自带的ORM,并注册celery相关应用

# getfiction/celery.py

from __future__ import absolute_import, unicode_literals
from celery import Celery
import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'getfiction.settings')  # 设置django环境
app = Celery('djcelery', broker='redis://127.0.0.1:6379/0', backend='django-db')
app.autodiscover_tasks()  # 发现任务文件每个app下的task.py

# getfiction/__init__.py

from __future__ import absolute_import, unicode_literals
from .celery import app as celery_app
import pymysql

__all__ = ['celery_app']
pymysql.install_as_MySQLdb()

# getfiction/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_celery_results',
    'getsection',
    'djcelery',
]

安装redis并启动:Release 3.0.504 · microsoftarchive/redis (github.com)

安装redis、eventlet模块:pip install redis eventlet

 安装celery相关模块

pip install celery django-celery django-celery-results

启动测试报错:

        1、cannot import name 'ugettext_lazy' from 'django.utils.translation'

        “ugettext_lazy”已被 Django 3+ 弃用,所以需要修改django的源码,如下:

        

 将ugettext_lazy使用gettext_lazy替代,修改如下:

# from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

重启项目,继续测试

        2、ModuleNotFoundError: No module named 'celery.five'

        版本不兼容,将celery的版本降到 4.4.7

pip install celery==4.4.7

重启项目,继续测试

        3、cannot import name 'force_unicode' from 'django.utils.encoding'

处理方式同上述1, 将 force_unicode替换为 force_str

# from django.utils.encoding import force_unicode as force_text  # noqa
from django.utils.encoding import force_str as force_text  # noqa

重启继续

        4、except self._encode_error, exc:

        anyjson不兼容python3,所以产生报错,下面会连续修改该模块相关源码,如下:

        

# GetFiction\venv\lib\site-packages\anyjson\__init__.py
    
88    except self._encode_error as exc:
89            raise (TypeError, TypeError(*exc.args), sys.exc_info()[2])

100   except self._decode_error as exc:
101           raise (ValueError, ValueError(*exc.args), sys.exc_info()[2])

120   print("Running anyjson as a stand alone script is not supported")

67    if isinstance(modinfo["encerror"], str):
69    if isinstance(modinfo["encerror"], str):

         5、from django.utils.translation import ugettext_lazy as _  错误同 1,

        6、from django.utils.translation import ungettext, ugettext as _ 与1类似

        

from django.utils.translation import gettext, gettext as _
# from django.utils.translation import ungettext, ugettext as _

        7、cannot import name 'force_unicode' from 'django.utils.encoding'

# venv/Lib/site-packages/djcelery/admin.py
from django.utils.encoding import force_str as force_text  # noqa

至此,修改源码部分完成

3、添加任务,执行,写入到数据库

 数据库迁移

python manage.py makemigrations   #生成迁移文件
python manage.py migrate          #执行迁移,生成数据表

创建发送任务视图函数:

# getsection/views.py

from django.shortcuts import HttpResponse
from getfiction.settings import logger
from getsection.tasks import getfictioninfo
from playwright.sync_api import sync_playwright


def index(request):
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        base_url = "https://www.83ks.org"
        # https://www.83ks.org/read/196719/2535054.html 某一章的内容
        page.goto(f"{base_url}/book/196719/")
        element_href = page.query_selector_all("#list dl a")
        novel_href_dic = {}
        if element_href:
            for i in element_href[:5]:
                c = [i.get_attribute('href')] + i.get_attribute('title').split(" ")[:0:-1]
                if len(c) < 3:
                    logger.error(str(c) + "该章节存在错误")
                elif len(c) == 4:
                    c.remove("lwxs.com")
                    novel_href_dic[c[-1]] = c[:2]
                else:
                    novel_href_dic[c[-1]] = c[:2]
        browser.close()
    for secindex, url_and_secname in novel_href_dic.items():
        getfictioninfo.delay(secindex, url_and_secname)
    return HttpResponse("OK")

安装playwright模块:pip install playwright

# getsection/tasks.py

from __future__ import absolute_import
from celery import shared_task
from playwright.sync_api import sync_playwright
from getfiction.settings import logger



@shared_task
def getfictioninfo(secindex, url_and_secname):
    # 第68章  ['/read/196719/1660838.html', '势不可挡']
    with sync_playwright() as p:
        browser = p.chromium.launch()
        section_page = browser.new_page()
        section_url = "https://www.83ks.org" + url_and_secname[0]
        try:
            section_page.goto(section_url)
        except Exception as e:
            logger.error(str(secindex) + str(e))
        section_page_element = section_page.query_selector_all("#content p")
        section_name = secindex + " " + url_and_secname[1] + "\n"
        logger.info(section_name)
        for i in section_page_element:
            section_name += i.inner_text() + " "
        return section_name

启动celery:celery -A getfiction worker -l info -P eventlet  

启动django:python manage.py runserver 0.0.0.0:8000

访问首页,进行测试:

数据存储,如下:

 django_celery_results_taskresult

 存在的问题,版本存在不兼容的问题,尚需优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1581800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

K8S:常用资源对象操作

文章目录 一、使用Replication Controller(RC)、Replica Set(RS) 管理Pod1 Replication Controller&#xff08;RC&#xff09;2 Replication Set&#xff08;RS&#xff09; 二、Deployment的使用1 创建2 滚动升级3 回滚Deployment三、 Pod 自动扩缩容HPA1 使用kubectl autosc…

大创项目推荐 深度学习 机器视觉 车位识别车道线检测 - python opencv

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) …

关于转义符 \ 在php正则中的匹配问题

今天做题遇到一个很经典的问题&#xff0c;记录一下&#xff0c;先看一段代码 <?php $str&#xff0c;&#xff0c;"\\"; $pattern&#xff0c;&#xff0c;"/\\/"; if(preg_match($partern,$str,$arr)) { &#xff0c;&#xff0c;&#xff0c;&…

Linux内核自带的LED驱动实验:确认驱动使能与Led设备节点

一. 简介 前面几篇文章学习了如何使用Linux内核自带的Led驱动。一篇文章通过对驱动分析&#xff0c;了解了驱动与设备匹配的关键点。 一篇文章学习了如何配置使能Linux内核自带的Led驱动&#xff0c;第二篇文章学习创建Led设备树节点&#xff08;针对使用Linux内核自带的Led…

C语言 常量

本文 我们说说 C语言 其他数据的表示 常量 首先 我们上文也说过&#xff1a;变量是可以改变值的量&#xff0c;而常量是不能改变值的量。 也就是 一个在变化过程中&#xff0c;始终不变的量 字面常量 字面常量 意思是 直接输入程序中的常量 所谓字面 就是写程序 直接以值的…

libVLC 提取视频帧使用QGraphicsView渲染

在前面章节中&#xff0c;我们讲解了如何使用QWidget渲染每一帧视频数据&#xff0c;这种方法对 CPU 负荷较高。 libVLC 提取视频帧使用QWidget渲染-CSDN博客 后面又讲解了使用OpenGL渲染每一帧视频数据&#xff0c;使用 OpenGL去绘制&#xff0c;利用 GPU 减轻 CPU 计算负荷…

Kubernetes 升级不弃 Docker:KubeKey 的丝滑之道

作者&#xff1a;尹珉&#xff0c;KubeSphere Ambaasador&Contributor&#xff0c;KubeSphere 社区用户委员会杭州站站长。 引言 随着 Kubernetes 社区的不断发展&#xff0c;即将迎来 Kubernetes 1.30 版本的迭代。在早先的 1.24 版本中&#xff0c;社区作出一个重要决策…

LeetCode_144(二叉树前序遍历)

1.递归 public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res new ArrayList<>();accessTree(root,res);return res;}public void accessTree(TreeNode root,List<Integer>res){if(root null){return;}res.add(root.val);acce…

EasyPOI复杂表格导入

EasyPOI复杂表格导入 多表头数据导入方式一导入表格实体类文件导入代码测试结果 方式二导入表格实体类文件导入代码测试结果 总结 设置表格从哪行读取表格内容 多表头数据导入 方式一 导入的表格样式如下 导入表格实体类 package com.demo.entity;import cn.afterturn.eas…

基于springboot实现常州地方旅游管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现旅游管理系统演示 摘要 随着旅游业的迅速发展&#xff0c;传统的旅游信息查询方式&#xff0c;已经无法满足用户需求&#xff0c;因此&#xff0c;结合计算机技术的优势和普及&#xff0c;针对常州旅游&#xff0c;特开发了本基于Bootstrap的常州地方旅游管…

1.微服务

一、微服务是什么 微服务是一种架构风格&#xff0c;即&#xff0c;一个应用应该是一组小型服务&#xff0c;每个服务器只负责一种服务&#xff0c;服务之间可以通过 HTTP 的方式进行互通。每一个功能元素最终都是一个可独立替换和独立升级的软件单元。 可以说&#xff0c;微…

湖北省武汉市二级分类30米土地利用数据下载

武汉市&#xff0c;湖北省省会&#xff0c;位于湖北省东部、长江与汉水交汇处&#xff0c;总面积8569.15平方千米。全市低山、丘陵、垄岗平原与平坦平原的面积分别占土地总面积的5.8%、12.3%、42.6%和39.3%&#xff0c; 湖北省武汉市土地利用数据是在对植被生长较好时间的Lands…

Linux进阶篇:centos7扩展root分区:LVM应用案例

centos7扩展root分区&#xff1a;LVM应用案例 当服务器根分区或者是root分区存储空间快用完的时候&#xff0c;并且重要的数据都在root分区下&#xff0c;当如何应对&#xff0c;没关系坐好&#xff0c;分分钟解决它&#xff0c;我们可以进行分区扩容。 一 添加一块新的硬盘 …

少儿编程 2024年3月电子学会图形化编程等级考试Scratch二级真题解析(选择题)

2024年3月scratch编程等级考试二级真题 选择题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 1、默认小猫角色&#xff0c;运行程序后&#xff0c;舞台上出现的图形是 A、 B、 C、 D、 答案&#xff1a;A 考点分析&#xff1a;考查积木综合使用&…

Java常见算法_常见的查找算法和排序算法——简介及代码演示

在本文中我将介绍Java中的常见算法&#xff0c;查找算法包括基本查找、二分查找、插值查找和分块查找。排序算法包括冒泡排序、选择排序、插入排序和快速排序 查找算法&#xff1a; 1.基本查找&#xff1a; 代码&#xff1a; public class BasicSearchDemo {public static …

多线程学习-Lock锁以及监视器锁详解

目录 1. Lock锁 1.1 Lock锁介绍 1.2 Lock锁的其他加锁方式 1.3 Lock和synchronized对比 2.监视器锁 1. Lock锁 1.1 Lock锁介绍 我们知道使用同步方法或同步代码块会自动加锁和解锁&#xff0c;那有没有办法可以自己控制加锁和解锁的时机呢&#xff1f; java在JDK1.5之后提供了…

BoostCompass(数据准备预处理模块)

阅读导航 一、网页数据下载二、编写数据去标签与数据清洗的模块 Parser✅boost 开发库的安装1. 基本思路2. 详细讲解&#xff08;1&#xff09;程序递归遍历目录&#xff0c;收集所有HTML文件的路径&#xff08;2&#xff09;对每个HTML文件进行解析&#xff0c;提取出文档标题…

政安晨:【深度学习神经网络基础】(五)—— 霍普菲尔德神经网络和玻尔兹曼机

目录 简述 霍普菲尔德神经网络 训练霍普菲尔德神经网络 Hopfield-Tank神经网络 玻尔兹曼机 总之 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 政安晨的机器学习笔记 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&am…

Python学习笔记10 - 程序的组织结构

1. if 语句 2. pass语句 3. 内置函数range() 4. while 循环语句 5. for-in 循环语句 6. 流程控制语句 break 7. 流程控制语句 continue 8. else 语句 9. 嵌套循环

申请GeoTrust证书

GeoTrust是全球知名的数字证书颁发机构&#xff08;CA&#xff09;和安全解决方案提供商。它成立于1999年&#xff0c;后来成为DigiCert旗下的一部分。GeoTrust专注于提供SSL证书和其他安全产品&#xff0c;以保护网站流量、电子邮件通信和企业身份的安全。 GeoTrust的SSL证书在…