参考: rest-framework框架基础组件, 基于Token的WEB后台认证机制,rest-framework之序列化组件

restful组件-1

一、序列化

对比:自己写的 for循环处理 (相对麻烦)django自带序列化工具 (不可控, 字段太多, 会造成网络拥堵问题)restful工具可控,但配置比较多, 后续会轻松些

1.1、django自带serializers

  • 使用说明
# 1、导入    from django.core import serializers
# 2、实例化   res = serializers.serialize('json', queryset)
  • 例子
from app01.models import Authers
from django.core import serializers
from rest_framework.views import APIView
from django.http.response import JsonResponseclass Mydjangoser(APIView):def get(self, reuqest):auther = Authers.objects.all()ser = serializers.serialize('json', auther)# safe=False 如果不设置这个 当字典中还有列表时返回就会报错return JsonResponse(ser, safe=False)# 访问,因为序列化已经是字符串了,所以看的结果就是ascii
"[{\"model\": \"app01.authers\", \"pk\": 1, \"fields\": {\"name\": \"xiong\", \"pwd\": \"12\"}}, {\"model\": \"app01.authers\", \"pk\": 2, \"fields\": {\"name\": \"we\", \"pwd\": \"321\"}}]"# 可以直接返回 HttpResponse  return HttpResponse(ser)
[{"model": "app01.authers", "pk": 1, "fields": {"name": "xiong", "pwd": "12"}}, {"model": "app01.authers", "pk": 2,
"fields": {"name": "we", "pwd": "321"}}]# 字典中的字段无用的就太多了会给网络带来拥堵

1.2、drf的Serializer

  • 使用说明
# 1、先在 setting.py中注册 restful
# 2、导入 from rest_framework import serializers
# 3、引用 res = AutherSerializer(instance=queryset对象, many=True)
# 4、返回数据 res.data
  • 继承serializers.Serializers

    # 想序列化哪一个模型就将字段序列化
    class AutherSerializer(serializers.Serializer):name = serializers.CharField()age = serializers.CharField()
    
  • 类使用

class Mydjangoser(APIView):def get(self, reuqest):auther = Authers.objects.all()# 初始化方法 def __init__(self, instance=None, data=empty, **kwargs)# many 如果传true说明queryset对象中有多条,   kwargs.pop('many', None)# many 传false说明就只有一条字典res = AutherSerializer(instance=auther, many=True)# res.data 获取序列化的数据return JsonResponse(res.data, safe=False)# 返回结果 [{"name": "xiong","pwd": "12"},{"name": "we","pwd": "321"}]

1.2.1、Serializer-source

# 模型: class Userinfo(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=32)pwd = models.CharField(max_length=64)userdetail = models.OneToOneField(to="Userdetail", to_field="id", on_delete=models.CASCADE)class Userdetail(models.Model):id = models.AutoField(primary_key=True)phone = models.IntegerField(max_length=13)email = models.EmailField()# 视图class MyUser(APIView):def get(self, request, *args, **kwargs):user_list = Userinfo.objects.all()users = UserSerializers(instance=user_list, many=True)return JsonResponse(users.data, safe=False)
  • 正常

    # 序列化
    from rest_framework import serializersclass UserSerializers(serializers.Serializer):name = serializers.CharField()pwd = serializers.CharField()userdetail = serializers.CharField()[{"name": "xiong","pwd": "123","userdetail": "Userdetail object (1)"},{"name": "hello","pwd": "321","userdetail": "Userdetail object (2)"}]
    
  • **source属性-1 修改名称 **

    # 将name修改为hello
    class UserSerializers(serializers.Serializer):hello = serializers.CharField(source="name")pwd = serializers.CharField()userdetail = serializers.CharField()[{"hello": "xiong","pwd": "123","userdetail": "Userdetail object (1)"},{"hello": "hello","pwd": "321","userdetail": "Userdetail object (2)"}]
    
  • source属性-2 一对一

class UserSerializers(serializers.Serializer):hello = serializers.CharField(source="name")pwd = serializers.CharField()userdetail = serializers.CharField(source="userdetail.email")[{"hello": "xiong","pwd": "123","userdetail": "22@qq.com"},{"hello": "hello","pwd": "321","userdetail": "33@qq.com"}]

1.2.2、SerializerMethodField

  • 正常写法
class UserSerializers(serializers.Serializer):hello = serializers.CharField(source="name")pwd = serializers.CharField()userdetail = serializers.SerializerMethodField()# 这里的obj 其实就是 userinfo 的对象def get_userdetail(self, obj):return obj.userdetail.email[{"hello": "xiong","pwd": "123","userdetail": "22@qq.com"},{"hello": "hello","pwd": "321","userdetail": "33@qq.com"}]
  • 返回关连表的全部, 像这样就需要一个一个的拼接比较麻烦
class UserSerializers(serializers.Serializer):hello = serializers.CharField(source="name")pwd = serializers.CharField()userdetail = serializers.SerializerMethodField()def get_userdetail(self, obj):# obj就是一个一个的对象, 类似于已经  .first了return {"email": obj.userdetail.email, "phone": obj.userdetail.phone}
  • 多表关连 - 写法1
# 单表没有.all属性,切记切记,
class UserSerializers(serializers.Serializer):name = serializers.CharField()user = serializers.CharField()publish = serializers.SerializerMethodField()def get_publish(self, obj):xx = obj.publish.all()return [{"name": x.name} for x in xx]
  • 多表关连- 写法2
class PublishSerializers(serializers.Serializer):name = serializers.CharField()class UserSerializers(serializers.Serializer):name = serializers.CharField()user = serializers.CharField()publish = serializers.SerializerMethodField()def get_publish(self, obj):xx = obj.publish.all()xy = PublishSerializers(instance=xx, many=True)return xy.data

1.2.3、ModelSerializer

  • 获取全部属性的方法
from app01.models import *
from rest_framework import serializersclass BookSerializer(serializers.ModelSerializer):# 元属性, 固定格式如下class Meta:model = Bookfields = "__all__"# 返回结果为 [{"id": 1, "name": "linux", "user": 1, "publish": [ 1 ]},.....]
  • 只显示某个值(类型于白名单)
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ["name", "user"]
# 返回结果: [{"name": "linux", "user": 1},.....]
  • 不显示某些值(黑名单)
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookexclude = ["id"]user = serializers.CharField(source="user.name")
# 返回结果为 [{"name": "linux", "user": 1, "publish": [ 1 ]},.....]
  • depth 深度

    class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookexclude = ["id"]depth = 3     # 官方建议是10层,但如果表的字段很多会造成性能问题,建议2-3层
    
  • 配合source使用

    class BookSerializer(serializers.ModelSerializer):class Meta:model = Book# fields = "__all__"fields = ["name", "user"]user = serializers.CharField(source="user.name")
    # 返回结果: [{"name": "linux", "user": "xiong"},.....]
    
  • 配合 ModelSerializer

class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookexclude = ["id"]user = serializers.CharField(source="user.name")publish = serializers.SerializerMethodField()def get_publish(self, publish_obj):publish_all = publish_obj.publish.all()print(publish_all) # <QuerySet [<Publish: Publish object (1)>]>return PublishSerializers(publish_all, many=True).data# 返回结果[{"user": "xiong", "publish": [{"name": " 上海出版"}],"name": "linux"},...]

1.2.4、HyperlinkedIdentityField

鸡肋,并没有什么用,URL前台拼就行

  • 序列化

    # class BookSerializer(serializers.Serializer):
    #     name = serializers.CharField()
    #     publish = serializers.HyperlinkedIdentityField(view_name="publish",
    #                                                    lookup_url_kwarg="pk",
    #                                                    lookup_field="publish")class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookexclude = ["id"]publish = serializers.HyperlinkedIdentityField(view_name="publish",lookup_url_kwarg="pk",lookup_field="pk")# view_name:  视图别名, lookup_url_kwarg: url后传的参数,
    # lookup_field: 本表的字段ID
    # lookup_url_kwarg 相当于是key,  lookup_field相当是value
    
  • 路由函数

from django.urls import re_path
from app01.views import *urlpatterns = [re_path("publish/(?P<pk>\d+)", Mypublish.as_view(), name="publish"),
]
  • 视图

    class Mypublish(APIView):def get(self, request, pk):response = {"status": 1000, "msg": None}res = Publish.objects.filter(pk=pk).first()if res:res_ser = PublishSerializers(instance=res, many=False)response["msg"] = res_ser.dataelse:response["status"] = 1002response["msg"] = "没有这个字段"return JsonResponse(response, safe=False)
    
  • error_messages

# 错误字段显示为中文name = serializers.CharField(error_messages={"required": "必填字段"})

1.3、反序列化

保存和修改, 必须是继承了ModelSerializer的类才能使用

  • 保存
class Mybook(APIView):def get(self, request, *args, **kwargs):book_list = Book.objects.all()books = BookSerializer(instance=book_list, many=True, context={'request': request})return JsonResponse(books.data, safe=False)def post(self, request, *args, **kwargs):response = {"status": 1000, "msg": None}data = request.data# 数据检验ret = BookSerializer(data=data, many=False)# 检验数据是否正常if ret.is_valid():# 如果 是多对多表,这里需要做一下检验,比如是不是列表,是否为空xx = ret.save()  # 保存类型: <class 'app01.models.Book'>publists = data.get("publish")if publists:if isinstance(publists, list):for p_num in publists:p = Publish.objects.filter(pk=p_num).first()xx.publish.add(p)else:p = Publish.objects.filter(pk=data.get("publish")).first()xx.publish.add(p)response["msg"] = "添加成功"else:response["status"] = 1002response["msg"] = "没有这个字段"return JsonResponse(response, safe=False)
  • 修改

    class Mybookdetail(APIView):def get(self, request, pk, *args, **kwargs):response = {"status": 1000, "msg": None}book_detail = Book.objects.filter(pk=pk).first()if book_detail:ret = BookSerializer(instance=book_detail, many=False)response["msg"] = ret.datareturn JsonResponse(response, safe=False)def put(self, request, pk, *args, **kwargs):response = {"status": 1000, "msg": None}book_detail = Book.objects.filter(pk=pk).first()if book_detail:# BookSerializer(data=book_detail, )ret = BookSerializer(data=request.data, instance=book_detail)data = request.data# ==================== 与添加一样# 检验数据是否正常if ret.is_valid():# 如果 是多对多表,这里需要做一下检验,比如是不是列表,是否为空xx = ret.save()  # 保存类型: <class 'app01.models.Book'>publists = data.get("publish")if publists:if isinstance(publists, list):for p_num in publists:p = Publish.objects.filter(pk=p_num).first()xx.publish.add(p)else:p = Publish.objects.filter(pk=publists).first()xx.publish.add(p)response["msg"] = "添加成功"else:response["status"] = 1001response["msg"] = ret.errorsreturn JsonResponse(response, safe=False)
    
  • 总结

# 添加: 获取数据并检验,最后给它保存ret = BookSerializer(data=data, many=False)if ret.is_valid(): ret.save()# 修改: 与添加不同的是, 获取数据前,需要先前修改的数据取出,然后在做检验最后保存ret = BookSerializer(data=request.data, instance=book_detail)if ret.is_valid(): ret.save()

1.4、钩子函数

1.4.1、源码分析

if ret.is_valid(): ret.save() # 直接从属性方法这进入到检验中, 需要注意的是 self.的都需要从第一级重新开始找, MRO

  • 检验方法is_valid
def is_valid(self, raise_exception=False):if not hasattr(self, '_validated_data'):try:# 这里是获取到全局的属性值self._validated_data = self.run_validation(self.initial_data).....if self._errors and raise_exception:raise ValidationError(self.errors)return not bool(self._errors)
  • self.run_validation

    self.run_validation, 已知self是 BookSerializer,从父属性开始找# 找到 Serializer/run_validationdef run_validation(self, data=empty):# 这里返回的是每个参数的值value = self.to_internal_value(data)try:self.run_validators(value)value = self.validate(value)assert value is not None, '.validate() should return the validated data'except (ValidationError, DjangoValidationError) as exc:raise ValidationError(detail=as_serializer_error(exc))return value
    
  • value = self.validate(value), 全局钩子函数

    # value = self.validate(value), 获取到这个属性,就是全局钩子函数,我们可以使用派生修改它def validate(self, attrs):return attrs     # 返回的结果就是每个序列化的值, 全局钩子函数
    
  • self.to_internal_value(data)

# 这里返回的是每个参数的值value = self.to_internal_value(data)# 局部钩子函数def to_internal_value(self, data):# filds 就是 user = serializers.CharField, 将其变为字典for field in fields:# 'validate_' + field.field_name 拼接的属性,这里就是局部的钩子函数# 如果没有就是 none, 使用的restful自带的检验validate_method = getattr(self, 'validate_' + field.field_name, None)primitive_value = field.get_value(data)....return ret

1.4.2、钩子

class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookexclude = ["id"]# 局部钩子def validate_name(self, data):if len(data) >=10:raise ValidationError("长度不能大于10")return data#  错误显示: "name": [ "长度不能大于10" ]# 全局钩子def validate(self, data):print("全局钩子")return data     # 必须要返回data# assert value is not None, '.validate() should return the validated data'

二、认证

2.1、认证源码分析

  • 从url开始 path("atest/", Atest.as_view()),

  • 进入到 ApiView/as_view()函数中

    @classmethoddef as_view(cls, **initkwargs):# 继承了父类的 as_view方法view = super().as_view(**initkwargs)view.cls = clsview.initkwargs = initkwargsreturn csrf_exempt(view)
  • 此时是父类的 View/as_view

        @classonlymethoddef as_view(cls, **initkwargs):......def view(request, *args, **kwargs):.....# 注意,这里的self是 函数也就是Atest, 又从 ApiView重新开始找return self.dispatch(request, *args, **kwargs)
    
  • 进入到 ApiView/dispatch中

    def dispatch(self, request, *args, **kwargs):self.args = argsself.kwargs = kwargs# 在这里重新封装了 request,进入查看request = self.initialize_request(request, *args, **kwargs)self.request = requestself.headers = self.default_response_headers  # deprecate?try:self.initial(request, *args, **kwargs)......except Exception as exc:response = self.handle_exception(exc)self.response = self.finalize_response(request, response, *args, **kwargs)return self.response
  • request = self.initialize_request(request, *args, **kwargs)

        def initialize_request(self, request, *args, **kwargs):"""Returns the initial request object."""parser_context = self.get_parser_context(request)# 返回的是重新封装好的Requestreturn Request(request,parsers=self.get_parsers(),# authenticators, 认证模块authenticators=self.get_authenticators(),negotiator=self.get_content_negotiator(),parser_context=parser_context)
    
  • authenticators=self.get_authenticators(),

    # 也就是说  authenticators 返回的是一个个的列表套对象  [对象内存地址1,2,3 ]def get_authenticators(self):return [auth() for auth in self.authentication_classes]# 默认的配置文件authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
  • self.initial(request, *args, **kwargs)

        def initial(self, request, *args, **kwargs):"""Runs anything that needs to occur prior to calling the method handler."""self.format_kwarg = self.get_format_suffix(**kwargs)# Perform content negotiation and store the accepted info on the requestneg = self.perform_content_negotiation(request)request.accepted_renderer, request.accepted_media_type = neg# Determine the API version, if versioning is in use.version, scheme = self.determine_version(request, *args, **kwargs)request.version, request.versioning_scheme = version, scheme# Ensure that the incoming request is permittedself.perform_authentication(request)self.check_permissions(request)self.check_throttles(request)
    
  • self.perform_authentication(request)

        def perform_authentication(self, request):# 最终返回的就是一个request.userrequest.user
    
  • 继续往下看 request.user属性 from rest_framework.request import Request

# 进入Request中找着 user方法@propertydef user(self):if not hasattr(self, '_user'):# 错误处理with wrap_attributeerrors():self._authenticate()return self._user
  • 进入认证 self._authenticate()

    # 需要注意的是def user(self)的这个self, 其实是request参数def _authenticate(self):'''循环 self.authenticators其实就是 request.authenticators,相当于是def get_authenticators(self):return [auth() for auth in self.authentication_classes]'''for authenticator in self.authenticators:try:user_auth_tuple = authenticator.authenticate(self)except exceptions.APIException:self._not_authenticated()raise....
    
  • user_auth_tuple = authenticator.authenticate(self)

    def authenticate(self, request):return (self.force_user, self.force_token)

2.2、入门示例

  • 模型
class Users(models.Model):username = models.CharField(max_length=32)pwd = models.CharField(max_length=12)class Token(models.Model):token = models.CharField(max_length=64)user = models.OneToOneField(to=Users, to_field="id", on_delete=models.CASCADE)
  • 登陆
class Login(APIView):def post(self, request, *args, **kwargs):response = {"status": 1000, "msg": "登陆成功"}username = request.data.get("uesrname")pwd = request.data.get("pwd")print(request.data)ret = Users.objects.filter(username=username, pwd=pwd).first()if not ret:token = uuid.uuid4()Token.objects.create(token=token, user=ret)response["token"] = tokenelse:response["status"] = 1001response["msg"] = "请先登陆"return JsonResponse(response, safe=False)
  • 认证
class Auth:# 源码中的这一个 user_auth_tuple = authenticator.authenticate(self)# self就是需要传递的参数def authenticate(self, request):token = request.query_params.get("token")ret = Token.objects.filter(token=token).first()if not ret:raise exceptions.APIException("请先登陆")return ret.user, ret
  • 认证的模型
# 在需要被定义认证的类下中写, 需要注意的是,这里最多只能写三个,
# 并且如果AUth有返回值,后面的认证组件就不会在执行
class Mybookdetail(APIView):# 在需要认证的模型上添加authentication_classes = [Auth, ]

2.3、使用

2.3.1、全局使用

# # settings.py文件中定义, 所有的组件都可以放在这里
REST_FRAMEWORK = {"DEFAULT_AUTHENTICATION_CLASSES": ["app01.rest_auth.Auth"]
}
# 需要注意的是,如果定义了全局,那么直接使用login也会受到限制

2.3.2、局部使用\禁用

# 局部禁用
class Mybookdetail(APIView):authentication_classes = []  # 直接设置为空就行# 局部使用
class Mybookdetail(APIView):authentication_classes = [PostAuth, ]

2.3.4、BaseAuthentication

# 继承基础组件, 也可以不继承
from rest_framework.authentication import BaseAuthentication
# 这个基础组件其实啥也没写, 关键在于就是继承authenticate_header头部类class BaseAuthentication(object):def authenticate(self, request):raise NotImplementedError(".authenticate() must be overridden.")def authenticate_header(self, request):pass

2.4、忽略GET

# 1、先配置全局使用
# 2、允许GET属性查看, 其它的方法都需要登陆才能操作
class PostAuth(BaseAuthentication):def authenticate(self, request):http_method_names = ['post', 'put', 'patch', 'delete', 'head', 'options', 'trace']print(request.method)if request.method.lower() in http_method_names:token = request.query_params.get("token")ret = Token.objects.filter(token=token).first()if not ret:raise exceptions.APIException("请先登陆")return ret.user, retreturn

3、demo

公共使用

  • setting.py
# 让全局生效
REST_FRAMEWORK = {"DEFAULT_AUTHENTICATION_CLASSES": ["app01.appAuthenticate.App01_authent", ]
}
  • urls.py
from django.contrib import admin
from django.urls import path
from app01 import viewsurlpatterns = [path('admin/', admin.site.urls),path("mybook/", views.Mybook.as_view(), name="mybook"),path("login/", views.Login.as_view(), name="login"),path("logout/", views.logout, name="logout"),
]
  • logout

    def logout(request):auth.logout(request)return JsonResponse({"status": 1000, "msg": "退出成功"})class Mybook(APIView):def get(self, request, *args, **kwargs):response = {"status": 1000, "msg": None}book_list = Book.objects.all()if all([book_list, ]):ser = BookSerializer(book_list, many=True)response["data"] = ser.dataresponse["msg"] = "查询成功"else:response["msg"] = "查询列表为空"return JsonResponse(response)
    

3.1、token判断

  • 模型
from django.db import models
from django.contrib.auth.models import Userclass UserToken(models.Model):token = models.CharField(max_length=64)user = models.OneToOneField(to=User, to_field="id", on_delete=models.CASCADE)
  • view
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from app01.appSerializer import BookSerializer
from app01.models import *
from django.http import JsonResponse
from django.contrib import auth
import uuidclass Login(APIView):authentication_classes = []def get(self, request):return render(request, "test.html")def post(self, request):response = {"status": 1000, "msg": "登陆成功"}username = request.data.get("username")pwd = request.data.get("pwd")ret = auth.authenticate(request, username=username, password=pwd)if ret:auth.login(request, ret)token = uuid.uuid4()# 存到session中进行判断 request.session["token"] = str(token)UserToken.objects.update_or_create(user=ret, defaults={"token": token})else:response["msg"] = "登陆失败"return JsonResponse(response)
  • 认证
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from app01.models import *# Create your views here.class App01_authent(BaseAuthentication):def authenticate(self, request):try:token = request.session["token"]if token:ret = UserToken.objects.filter(token=token).first()if not ret:raise exceptions.APIException("认证失败")return ret.user, tokenexcept Exception:raise exceptions.APIException("请先登陆")

3.2、session表中判断

在自定义token减少操作

  • App01_authent

    class App01_authent(BaseAuthentication):def authenticate(self, request):try:# 取出用户的 session, 如果没有登陆数据库中不会保存token = request.session.session_keyif token:ret = Session.objects.filter(session_key=token).first()if not ret:raise exceptions.APIException("认证失败")# 返回用户,跟token, return auth.get_user(request), tokenexcept Exception:raise exceptions.APIException("请先登陆")
    
  • views

class Login(APIView):authentication_classes = []def get(self, request):return render(request, "test.html")def post(self, request):response = {"status": 1000, "msg": "登陆成功"}username = request.data.get("username")pwd = request.data.get("pwd")ret = auth.authenticate(request, username=username, password=pwd)if ret:auth.login(request, ret)else:response["msg"] = "登陆失败"return JsonResponse(response)

python-restful-02-组件(序列化\认证)相关推荐

  1. 两个月不到,我是如何从Python新手成长为谷歌认证TensorFlow开发者的?

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 来自:机器之心 因为新冠疫情宅家无事可做,印度尼西亚一位应用数学学生 Grady Ma ...

  2. python建立数据库并序列化_python之数据的序列化

    参考博客:http://www.cnblogs.com/yyds/p/6563608.html 数据的序列化功能表 json.dumps() 将python数据类型转换为(json)字符串 json. ...

  3. python建立数据库并序列化_Python之数据序列化(json、pickle、shelve)

    一.python类型数据和JSON数据格式互相转换 pthon 中str类型到JSON中转为unicode类型,None转为null,dict对应object 二. 序列化/反序列化 将对象转换为可通 ...

  4. python中常用的序列化模块_使用pickle模块对python对象进行序列化

    pickle模块是Python自带的一个标准模块,专用于Python各种对象的序列化和反序列化,可用于Python内置的各种数据对象(Python中一切都是对象),也可用于程序员自定义的类和对象. p ...

  5. 一文学会Python标准库struct序列化与反序列化

    使用Python标准库struct序列化Python整数.实数.字节串时,需要使用struct模块的pack()函数把对象按指定的格式进行序列化,然后使用文件对象的write()方法将序列化的结果字节 ...

  6. Python 实现简单的客户端认证

    更多编程教程请到:菜鸟教程 https://www.piaodoo.com/ 友情链接: 高州阳光论坛https://www.hnthzk.com/ 人人影视http://www.op-kg.com/ ...

  7. “结巴”中文分词:做最好的 Python 中文分词组件

    jieba "结巴"中文分词:做最好的 Python 中文分词组件 "Jieba" (Chinese for "to stutter") C ...

  8. EN 12259-3喷水灭火系统干式报警阀组件—CE认证

    喷水灭火系统干式报警阀组件CE认证(欧盟强制认证)-简介 在欧盟市场"CE"标志属强制性认证标志,以表明产品符合欧盟<技术协调与标准化新方法>指令的基本要求.这是欧盟法 ...

  9. 3、Python 中文分词组件Jieba

    在自然语言处理中,分词是一项最基本的技术.中文分词与英文分词有很大的不同,对英文而言,一个单词就是一个词,而汉语以字为基本书写单位,词语之间没有明显的区分标记,需要人为切分.现在开源的中文分词工具有 ...

  10. Python 学习 02 —— Python如何爬取数据

    文章目录 系列文章 二.Python 爬 虫 1.任务介绍 2.简介 3.基本流程 3.1.准备工作 3.1.1.分析页面 3.1.2.编码规范 3.1.3.导入模块 3.1.4.程序流程 3.2.获 ...

最新文章

  1. postgresql(pg)数据库简介
  2. 注解由谁读取并解析的?
  3. windows下vagrant的安装使用
  4. 104 规约模拟器linux,变电站自动化系统调试装置 Substation automation system debugging device...
  5. 苹果爸爸发飙,封杀 React Native?
  6. 【开源资讯】开源文档管理系统 Wizard 1.2.5 发布
  7. SeSe 2005-02-11 -- 2005-02-12
  8. 记录一下:调试了虹软的人脸识别sdk,存到数据库中
  9. 处理minidump文件用到的“工具”的分享
  10. linux 修改密码 authen,Linux系统下root用户执行passwd修改密码时报错Authentication to
  11. GO的lua虚拟机 gopher-lua
  12. 前端容易忽略的 debugger 调试技巧
  13. 2022-03微软漏洞通告
  14. 如何彻底禁用谷歌Chrome更新
  15. vue项目微信公众号title设置和调用接口动态修改
  16. 设某种二叉树有如下特点:每个结点要么是叶子结点,要么有2棵子树。假如一棵这样的二叉树中有m(m0)个叶子结点,那么该二叉树上的结点总数为( )。
  17. matlab生成棋盘格网的命令,Matlab 画棋盘格
  18. HBase-Region的拆分与合并
  19. android的wifi网卡移植详细过程已经通用驱动的问题
  20. “达内”JAVA技术培训有感(二)

热门文章

  1. 开源求职招聘微信小程序源码+完整搭建教程
  2. 根据枚举code获取枚举值
  3. python作业习题
  4. 蓝牙耳机什么牌子的好用?口碑好的国产蓝牙耳机推荐
  5. SHT30 I2C 温湿度传感器实际应用
  6. 国家邮政局发布2021年快递服务满意度和时限准时率测结果
  7. VLayout中的横向瀑布流
  8. 计算机考试身份证、准考证都要带原件吗?
  9. 【力扣638】 大礼包问题 JAVA全过程详解,绝对易懂
  10. 31_ue4[动画]03_虚幻争霸角色重定向小白人