• [最佳实践] Python对接clickhouse
    Python对接clickhouseclickhouse通用jdbc端口clickhouse jdbc接口使用HTTP协议,具体对应华为clickhouse端口可以在Manager->clickhouse页面 逻辑集群部分查看针对非加密、加密端口,对接使用的jdbc url有区别,具体如下非加密端口 21426 对应jdbc连接 url为: jdbc:clickhouse://x.x.x.x:21426/default加密端口 21428 对应jdbc连接 url为: jdbc:clickhouse://x.x.x.x:21428/default?ssl=true&sslmode=none其中连接的ip 为 clickhouse balancer实例对应的ip注意:本次使用非加密端口进行对接前提条件安装python3环境,以及需要连接的MRS集群环境 1、 下载python3 源码 编译tar zxvf Python-3.8.0.tgz cd Python-3.8.0 mkdir -p /usr/local/python-3.8.0 ./configure --prefix=/usr/local/python-3.8.0 -enable-optimizations --with-ssl make && make install 编译 ln -s /usr/local/python-3.8.0/bin/python3 /usr/bin/python3 ln -s /usr/local/python-3.8.0/bin/pip3 /usr/bin/pip3 ll /usr/bin/python*使用通用jdbc进行连接安装对应依赖./pip3 install jpype1==1.4.1 ./pip3 install JayDeBeApi==1.2.3Python代码import jaydebeapi import jpype import os conn = jaydebeapi.connect("ru.yandex.clickhouse.ClickHouseDriver","jdbc:clickhouse://x.x.x.x:21426/default",["username","passwd"],jars=['/opt/lyf/lib1/clickhouse-jdbc-0.3.1-h0.cbu.mrs.320.r11.jar','/opt/lyf/lib1/commons-codec-1.15.jar','/opt/lyf/lib1/commons-logging-1.2.jar','/opt/lyf/lib1/httpclient-4.5.13.jar','/opt/lyf/lib1/httpcore-4.4.13.jar','/opt/lyf/lib1/lz4-java-1.7.1.jar','/opt/lyf/lib1/slf4j-api-1.7.36.jar','/opt/lyf/lib1/us-common-1.0.66.jar','/opt/lyf/lib1/bcprov-jdk15on-1.70.jar']) import pandas as pd sql = "Select * From addressbook" df_ck = pd.read_sql(sql, conn) df_ck conn.close()注解: 将所需的lib文件放在对应目录下commons-codec-1.15.jar commons-logging-1.2.jar httpclient-4.5.13.jar httpcore-4.4.13.jar lz4-java-1.7.1.jar slf4j-api-1.7.36.jar bcprov-jdk15on-1.70.jar clickhouse-jdbc-0.3.1-h0.cbu.mrs.320.r11.jar us-common-1.0.66.jar使用clickhouse_connect进行连接安装对应依赖./pip3 install clickhouse_connect==0.6.4 python代码import clickhouse_connect client = clickhouse_connect.get_client(host='x.x.x.x', port=21426, username='username', password='passwd') client.command('show tables') client.command('select * from people')注:参照cid:link_0FAQPython代码执行报错classnotfoundconn = jaydebeapi.connect("ru.yandex.clickhouse.ClickHouseDriver","jdbc:clickhouse:// x.x.x.x:port/default?ssl=true&sslmode=none?user=username&password=passwd!@",jars=['/opt/lyf/lib1/clickhouse-jdbc-0.3.1-h0.cbu.mrs.320.r11.jar'])查看该方法源码 help(jaydebeapi.connect)解决方法: 修改connection的参数设置为conn = jaydebeapi.connect("ru.yandex.clickhouse.ClickHouseDriver","jdbc:clickhouse://x.x.x.x:port/default",["username","passwd"],jars=['/opt/lyf/lib1/clickhouse-jdbc-0.3.1-h0.cbu.mrs.320.r11.jar','/opt/lyf/lib1/commons-codec-1.15.jar','/opt/lyf/lib1/commons-logging-1.2.jar','/opt/lyf/lib1/httpclient-4.5.13.jar','/opt/lyf/lib1/httpcore-4.4.13.jar','/opt/lyf/lib1/lz4-java-1.7.1.jar','/opt/lyf/lib1/slf4j-api-1.7.36.jar','/opt/lyf/lib1/us-common-1.0.66.jar','/opt/lyf/lib1/bcprov-jdk15on-1.70.jar'])python代码执行报错classnotfoundgrep –R ‘x.x.x.x’ 文件夹找到对应的jar包放到对应目录下,在jars参数上加上对应的jar包
  • [专题汇总] 都来看看啊 ,总有一篇能帮到你。6月份技术干货合集
     大家好本次整理的是codeArts6月份干货合集,希望可以帮到大家。 1.Go语言五大主流web框架-转载 https://bbs.huaweicloud.com/forum/thread-0213121661901680008-1-1.html  2.Vue中实现自定义excel下载-转载 https://bbs.huaweicloud.com/forum/thread-0278121662059656002-1-1.html  3.如何查看自己的操作系统是否支持 64 位架构 https://bbs.huaweicloud.com/forum/thread-0257121682060865007-1-1.html  4.Solr和Elasticsearch对比 https://bbs.huaweicloud.com/forum/thread-0253122347814807015-1-1.html  5.linux关于sed流编辑器那些事 https://bbs.huaweicloud.com/forum/thread-02116122519740471010-1-1.html  6.JS中的事件监听-转载 https://bbs.huaweicloud.com/forum/thread-0253122779497415032-1-1.html  7.浅谈DNS域名解析的过程-转载 https://bbs.huaweicloud.com/forum/thread-0253122779866795033-1-1.html  8.【服务器】利用树莓派搭建 web 服务器-无需公网IP-转载 https://bbs.huaweicloud.com/forum/thread-02106122779940418023-1-1.html  9.【vue3】使用canvas-转载 https://bbs.huaweicloud.com/forum/thread-0234122780116390011-1-1.html  10.前端面试八股文(超详细)-转载 https://bbs.huaweicloud.com/forum/thread-02116122780328089022-1-1.html  11.python数组和矩阵的区别 https://bbs.huaweicloud.com/forum/thread-0219123321311972030-1-1.html  12.Python NLP开发之实现聊天机器人【转】 https://bbs.huaweicloud.com/forum/thread-0253123321507470064-1-1.html  13.使用vbs脚本来监控windows服务器上的应用程序(不存在就启动)【转】 https://bbs.huaweicloud.com/forum/thread-02117123384453066001-1-1.html  14.vbs ShellExecute运行外部程序时如何判断外部程序执行成功与否【转】 https://bbs.huaweicloud.com/forum/thread-0212123384557753002-1-1.html  15.cmd批量ping命令的实现【转】 https://bbs.huaweicloud.com/forum/thread-0226123384655183003-1-1.html  16.批处理文件bat启动redis及任何软件【转】 https://bbs.huaweicloud.com/forum/thread-0212123384741335003-1-1.html  17.cmd实现清理系统垃圾的示例代码【转】 https://bbs.huaweicloud.com/forum/thread-0284123384865623001-1-1.html  18.cmd常用命令大全【转】 https://bbs.huaweicloud.com/forum/thread-0226123385078380004-1-1.html  19.window使用bat批处理文件执行cmd命令【转】 https://bbs.huaweicloud.com/forum/thread-0215123385522817002-1-1.html  20.DOS批处理字符串截取【转】 https://bbs.huaweicloud.com/forum/thread-02117123385670322002-1-1.html  21.批处理删除指定文件或文件夹的实现【转】 https://bbs.huaweicloud.com/forum/thread-02100123387214334003-1-1.html  22.批处理字符串截取的实现【转】 https://bbs.huaweicloud.com/forum/thread-0248123387845375003-1-1.html  23.Python中选择排序的实现与优化【转】 https://bbs.huaweicloud.com/forum/thread-02105123388234406002-1-1.html  24.flask+pymysql实现Web端操作数据库的项目实践【转】 https://bbs.huaweicloud.com/forum/thread-0248123388970328005-1-1.html  25.深入理解Python中的Contextlib库【转】 https://bbs.huaweicloud.com/forum/thread-02117123389149341007-1-1.html 
  • [技术干货] 深入理解Python中的Contextlib库【转】
    一、contextmanager装饰器contextmanager装饰器能让我们更简单的实现上下文管理器。上下文管理器通常用于封装起始和结束需要做的操作,例如打开和关闭文件,获取和释放锁等等。以下是一个使用contextmanager装饰器实现的上下文管理器例子:import contextlib @contextlib.contextmanager def managed_resource(*args, **kwds):     # Code to acquire resource, e.g.:     resource = acquire_resource(*args, **kwds)     try:         yield resource     finally:         # Code to release resource, e.g.:         release_resource(resource)在上述代码中,yield语句将产生一个上下文,用户可以使用这个上下文在with语句中。二、closing函数closing函数是一个帮助函数,用来确保对象的close方法在完成后被正确的调用。这对于一些提供了close方法但是没有实现上下文管理协议的对象非常有用。import contextlib with contextlib.closing(open('my_file.txt', 'w')) as f:     f.write('Hello, World!')在上述代码中,文件my_file.txt被打开,数据被写入,然后文件被正确的关闭,无论写入数据是否成功。三、其他有用的类和函数Contextlib库还提供了其他一些有用的类和函数,如ExitStack,nullcontext,和supress等。我们将在后续文章中详细介绍这些类和函数的用法和实例。目前,我们可以简单的了解一下他们的功能:ExitStack类允许我们更灵活地管理上下文资源。我们可以在一个ExitStack实例中添加任意多个上下文管理器,并保证所有的上下文管理器都会在退出时正确的执行清理操作。nullcontext是一个简单的上下文管理器,它不执行任何操作。这在某些需要动态决定是否使用上下文管理器的情况下非常有用。suppress函数可以用来忽略指定的异常。Contextlib库提供了一些强大的工具来帮助我们更好地管理和操作上下文。虽然在开始时可能需要一些时间来理解这些工具的工作原理,但是一旦掌握了,你会发现它们在实际编程中非常有用。四、ExitStack类的使用如前所述,ExitStack类是一个灵活的上下文管理器,它可以管理多个上下文管理器和一般的清理任务。下面是一些使用ExitStack的例子:from contextlib import ExitStack def archive_files(files, archive_name):     with ExitStack() as stack:         archive = stack.enter_context(open(archive_name, 'w'))         for file_name in files:             file = stack.enter_context(open(file_name))             archive.write(file.read())在这个例子中,我们首先创建了一个ExitStack实例,然后在这个实例中打开了一个用于存档的文件。然后,我们打开了一系列的文件,每打开一个文件,就将其添加到ExitStack实例中。无论过程中发生何种异常,ExitStack都会保证所有打开的文件在退出时都被正确关闭。五、nullcontext的使用nullcontext是一个非常简单的上下文管理器,它不执行任何操作。它的主要用途是在需要动态决定是否需要使用上下文管理器时作为一个占位符使用。以下是一个使用nullcontext的例子:import contextlib def optional_open(file_name, mode, use_context):     if use_context:         return open(file_name, mode)     else:         return contextlib.nullcontext() with optional_open('my_file.txt', 'w', False) as f:     if f is not None:         f.write('Hello, World!')在这个例子中,我们定义了一个函数optional_open,它根据传入的参数use_context决定是否使用open函数的上下文管理器。如果use_context为True,则使用open函数的上下文管理器;否则,使用nullcontext作为占位符。六、suppress函数的使用suppress函数可以用来忽略指定的异常。以下是一个使用suppress的例子:import contextlib with contextlib.suppress(FileNotFoundError):     os.remove('my_file.txt')在这个例子中,我们尝试删除一个文件。如果文件不存在,os.remove函数会抛出一个FileNotFoundError异常。通过使用suppress函数,我们可以忽略这个异常,使得代码即使在文件不存在的情况下也能正常执行。
  • [技术干货] flask+pymysql实现Web端操作数据库的项目实践【转】
    Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2 中则使用 mysqldb。PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。一.环境配置flask库和pymysql库使用pip接口进行安装:pip install flaskpip install pymysql二.实际应用1.首先先实现mysql的主程序,新建xxx.py文件:import pymysql class Mysql(object):     def __init__(self):         try:             self.db = pymysql.connect(host="localhost",user="root",password="密码",database="数据库名称")             #游标对象             self.cursor = self.db.cursor()             print("连接成功!")         except:             print("连接失败!")      # 查询数据函数     def getdata(self):         sql = "select * from 表名"         #执行sql语句         self.cursor.execute(sql)         #获取所有的记录         results = self.cursor.fetchall()         return results     #关闭     def __del__(self):         self.db.close()2.然后新建另一个xxx.py文件,运行flask框架,调用编好的html,实现web端输出数据库表内容。flask文件from flask import Flask,render_template,request app = Flask(__name__) @app.route("/select",methods=['GET','POST']) def select():     #调用     db = Mysql()     results = db.getdata()     return render_template("select.html",results=results) if __name__ == "__main__":     app.run(app.run(debug=True,port=5000,host='127.0.0.1'))html文件<body> <div>     <h4>查询数据</h4>     <table border="1" width="30%" weight="30%">         <thead>         <tr>             <th>id</th>             <th>worknumber</th>             <th>name</th>             <th>gender</th>             <th>age</th>             <th>idcard</th>             <th>entrydate</th>         </tr>         </thead>         <tbody>             {% for result in results %}                 <tr>                     <td>{{ result[0]}}</td>                     <td>{{ result[1]}}</td>                     <td>{{ result[2]}}</td>                     <td>{{ result[3]}}</td>                     <td>{{ result[4]}}</td>                     <td>{{ result[5]}}</td>                     <td>{{ result[6]}}</td>                     <td><a href="/delete?id={{ result[0] }}" rel="external nofollow" ><button>删除</button></a></td>                     <td><a href="/submit_insert" rel="external nofollow" ><button>插入</button></a></td>                     <td><a href="/submit_update" rel="external nofollow" ><button>修改</button></a></td>                 </tr>             {% endfor %}         </tbody>     </table> </div>3.运行flask文件,网页输入http://127.0.0.1:5000/select三.总结删除、插入、修改等操作同查询一样,这边就不放代码了!
  • [技术干货] Python中选择排序的实现与优化【转】
    选择排序(Selection Sort)是一种简单但有效的排序算法。它的基本思想是每次从待排序的元素中选择最小(或最大)的元素,并将其放置在已排序序列的末尾。通过多次选择和交换操作,逐步将序列排序。本文将详细介绍选择排序算法的原理和实现,并提供相关的Python代码示例。一、算法原理选择排序算法的步骤如下:遍历待排序序列,将第一个元素视为当前最小(或最大)元素。在剩余的待排序序列中,找到最小(或最大)的元素,将其与当前位置交换。排除已排序的元素,重复步骤2,直到所有元素都被排序。选择排序的核心思想是通过多次选择最小(或最大)元素,逐步将序列排序。二、选择排序的实现下面是使用Python实现选择排序算法的代码:def selection_sort(arr):     n = len(arr)     for i in range(n - 1):         # 假设当前位置的元素为最小值         min_index = i         for j in range(i + 1, n):             # 在剩余部分中寻找最小值的索引             if arr[j] < arr[min_index]:                 min_index = j                 # 将当前位置的元素与最小值进行交换         arr[i], arr[min_index] = arr[min_index], arr[i]         # 测试代码 numbers = [4, 2, 6, 1, 3] selection_sort(numbers) print(numbers)  # 输出:[1, 2, 3, 4, 6]在上述代码中,selection_sort()函数接受一个待排序的列表作为输入,并对列表进行选择排序。算法使用两个嵌套的循环。外部循环从第一个元素遍历到倒数第二个元素,内部循环从外部循环的下一个位置遍历到列表末尾,寻找最小元素的索引。然后通过交换操作,将最小元素放置在当前位置上。三、算法分析选择排序是一种原址排序算法,即在排序过程中直接修改原始列表,不需要额外的存储空间。选择排序的时间复杂度为O(n^2),其中n是待排序序列的长度。虽然选择排序的时间复杂度较高,但在小规模数据或部分有序的数据集上,其性能仍然可以接受。 选择排序是一种不稳定的排序算法,即相等元素的相对顺序可能会发生改变。例如,对于序列[2, 2, 1],经过选择排序后,第一个2会被移到第二个2的后面。四、优化思路尽管选择排序的时间复杂度较高,但可以通过一些优化思路提升算法性能。优化1:减少交换次数在内部循环中,我们每次找到最小元素后都会进行一次交换操作。实际上,我们可以在内部循环结束后再进行一次交换操作,将最小元素放置在正确的位置上。def selection_sort(arr):     n = len(arr)     for i in range(n - 1):         # 假设当前位置的元素为最小值         min_index = i         for j in range(i + 1, n):             # 在剩余部分中寻找最小值的索引             if arr[j] < arr[min_index]:                 min_index = j                 # 将当前位置的元素与最小值进行交换         if min_index != i:             arr[i], arr[min_index] = arr[min_index], arr[i]这样可以减少交换的次数,但并不会改变算法的时间复杂度。优化2:使用双指针在内部循环中,我们每次都要查找剩余部分中的最小元素的索引。可以使用双指针的方式,同时记录最小元素的索引和最大元素的索引,然后进行交换。def selection_sort(arr):     n = len(arr)     left = 0     right = n - 1     while left < right:         # 假设当前位置的元素为最小值和最大值         min_index = left         max_index = right         for i in range(left, right + 1):             # 在剩余部分中寻找最小值和最大值的索引             if arr[i] < arr[min_index]:                 min_index = i             if arr[i] > arr[max_index]:                 max_index = i                 # 将当前位置的元素与最小值进行交换         if min_index != left:             arr[left], arr[min_index] = arr[min_index], arr[left]         if max_index == left:             max_index = min_index             # 将当前位置的元素与最大值进行交换         if max_index != right:             arr[right], arr[max_index] = arr[max_index], arr[right]         left += 1         right -= 1这种优化方式可以同时找到最小元素和最大元素的索引,并进行相应的交换操作。在一次循环中,我们可以找到最小元素并将其放置在正确的位置上,同时找到最大元素并将其放置在正确的位置上。这样可以减少比较的次数。五、总结选择排序是一种简单但有效的排序算法。它的基本思想是每次选择最小(或最大)的元素,并将其放置在已排序序列的末尾,通过多次选择和交换操作,逐步将序列排序。本文介绍了选择排序算法的原理和实现,并提供了相关的Python代码示例。选择排序的时间复杂度为O(n^2),在小规模数据或部分有序的数据集上,其性能可以接受。此外,我们还介绍了一些优化思路,如减少交换次数和使用双指针,以提升算法的性能。掌握选择排序的实现和优化思路对于理解和应用其他排序算法也是很有帮助的。
  • [技术干货] Python NLP开发之实现聊天机器人【转】
    1、简介AI 聊天机器人使用自然语言处理 (NLP) 来帮助用户通过文本、图形或语音与 Web 服务或应用进行交互。聊天机器人可以理解自然人类语言、模拟人类对话并运行简单的自动化任务。此外,AI 聊天机器人还利用预测智能和分析技术来了解用户的偏好,并利用了解的这些信息来提供建议和预测需求AI 聊天机器人用于各种渠道,例如消息传递应用、移动应用、网站、电话线路和支持语音的应用。它们可以针对不同目的而开发,无论是仅处理一些简单的命令,还是充当复杂的数字助理和交互式代理。AI 聊天机器人可以是大型应用程序的一部分,也可以完全独立存在2、代码测试2.1 open.drea.ccimport requests import json while True:     msg = input('我:')     sess = requests.get(         ('https://open.drea.cc/bbsapi/chat/get?keyWord=' + msg + '&userName=type%3Dbbs'))     js = sess.text     js = json.loads(js)     print('微梦机器人:', js['data']['rep ly']) 2.2 api.ruyi.aiimport requests import json  while True:     msg = input('我:')     sess = requests.get(('http://api.ruyi.ai/v1/message?app_key=your_key&user_id=test123&q=' + msg))     js = sess.text     js = json.loads(js)     js = js['result']['intents']     js = js[0]['result']['text']     print('海知机器人:', js) 2.3 route.showapi.comimport requests import json while True:     msg = input('我:')     sess = requests.get(         ('http://route.showapi.com/60-27?&showapi_appid=102421&userid=userid&showapi_sign=your_key&info=' + msg))     js = sess.text     js = json.loads(js)     print('万维易源机器人:', js['showapi_res_body']['text'])2.4 api.binstd.comimport requests import json while True:     msg = input('我:')     sess = requests.get(         ('https://api.binstd.com/iqa/query?appkey=your_key&question=' + msg))     js = sess.text     js = json.loads(js)     print('进制机器人:', js['result']['content'])2.5 api.jisuapi.comimport requests import json while True:     msg = input('我:')     sess = requests.get(('https://api.jisuapi.com/iqa/query?appkey=c0e4885a90566a7b&question=' + msg))     js = sess.text     js = json.loads(js)     print('极速机器人:', js['result']['content'])2.6 api.fanyi.baidu.comimport requests import string import time import hashlib import json #init api_url = "http://api.fanyi.baidu.com/api/trans/vip/translate" my_appid = 'your_key' cyber = 'your_cyber ' lower_case = list(string.ascii_lowercase) def requests_for_dst(word):     #init salt and final_sign     salt = str(time.time())[:10]     final_sign = str(my_appid)+word+salt+cyber     final_sign = hashlib.md5(final_sign.encode("utf-8")).hexdigest()     #区别en,zh构造请求参数     if list(word)[0] in lower_case:         paramas = {             'q': word,             'from': 'en',             'to': 'zh',             'appid': '%s' % my_appid,             'salt': '%s' % salt,             'sign': '%s' % final_sign         }         my_url = api_url+'?appid=' + \             str(my_appid)+'&q='+word+'&from='+'en'+'&to=' + \             'zh'+'&salt='+salt+'&sign='+final_sign     else:         paramas = {             'q': word,             'from': 'zh',             'to': 'en',             'appid': '%s' % my_appid,             'salt': '%s' % salt,             'sign': '%s' % final_sign         }         my_url = api_url+'?appid=' + \             str(my_appid)+'&q='+word+'&from='+'zh'+'&to=' + \             'en'+'&salt='+salt+'&sign='+final_sign     response = requests.get(api_url, params=paramas).content     content = str(response, encoding="utf-8")     json_reads = json.loads(content)     print('小度机器人:这句话翻译为中文是',json_reads['trans_result'][0]['dst']) while True:     word = input("我: ")     requests_for_dst(word)
  • [技术干货] python数组和矩阵的区别
    在Python中,数组和矩阵是常用的数据结构,用于存储和处理多维数据。数组 (Array):数组是一种线性数据结构,可容纳固定数量的元素,这些元素可以是相同类型或不同类型。在Python中,我们通常使用NumPy库来处理数组。NumPy数组是由相同类型的元素组成的多W网格,并且可以进行高效的数值计算和操作。你可以使用NumPy库创建、访问、修改和操作数组,包括执行向量化操作、矢量化计算、广播等。示例代码:import numpy as np # 创建数组 arr = np.array([1, 2, 3, 4, 5])  # 访问数组元素 print(arr[0])  # 输出: 1  # 修改数组元素 arr[1] = 10  # 数组运算 arr2 = arr + 5   # 每个元素加上5  # 数组形状操作 arr3 = np.reshape(arr2, (2, 3))  # 将一维数组转为二维数组  # 数组计算 sum_arr = np.sum(arr)  # 计算数组元素的和 矩阵 (Matrix):矩阵是一个二维数据结构,由行和列组成,其中每个元素都有一对整数索引来标识其位置。在Python中,我们可以使用NumPy库创建和处理矩阵。NumPy的ndarray对象提供了与矩阵相关的功能。示例代码:import numpy as np  # 创建矩阵 mat = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])  # 访问矩阵元素 print(mat[0, 1])  # 输出: 2  # 修改矩阵元素 mat[1, 2] = 10  # 矩阵运算 mat2 = mat + 5   # 每个元素加上5  # 矩阵形状操作 mat3 = np.reshape(mat2, (3, 2))  # 改变矩阵形状为3行2列  # 矩阵计算 transpose_mat = np.transpose(mat)  # 矩阵转置 mat_product = np.dot(mat, mat2)  # 矩阵乘法 总结来说,数组更通用,可包含 n 维元素,而矩阵是特定的二维数据结构。NumPy库为这些数据结构提供了强大的功能和高效的操作,使得在Python中处理多维数据变得更加便捷和高效。
  • [技术干货] 绝地求生 压q python版-转载
     一、概述 1.1 效果 总的来说,这种方式是通过图像识别来完成的,不侵入游戏,不读取内存,安全不被检测。  1.2 前置知识 游戏中有各种不同的q械,不同的q械后坐力不一样,射速也不同。相同的q械,装上不同的配件后,后坐力也会发生变化。 q械的y轴上移是固定的,x轴是随机的,因此我们程序只移动鼠标y轴。x轴游戏中手动操作。 1.3 实现原理简述 通过python中的pynput模块监听键盘鼠标。 监听鼠标左键按下,这个时候开始移动鼠标。左键抬起,终止移动。 监听键盘按键,比如tab键,这时打开背包,截屏开始识别装备栏。  通过python的pyautogui模块来截屏,可以截取屏幕指定位置。  通过python的opencv模块来处理截取的图片。  通过SSIM算法来对比图片相似度,获取到装备栏的武器、配件。  通过python的pydirectinput操作鼠标移动。  二、详解 2.1 pynput监听键盘 import pynput.keyboard as keyboard  # 监听键盘 def listen_keybord():     listener = keyboard.Listener(on_press=onPressed, on_release=onRelease)     listener.start() pynput的监听为异步事件,但是会被阻塞,所以如果事件处理事件过长,得用异步处理。  2.2 监听事件 创建了c_equipment类来封装武器信息。 重点在tab键的监听,使用异步来检测装备信息。  def onRelease(key):     try:         if '1' == key.char:             c_equipment.switch = 1 #主武器1         elif '2' == key.char:             c_equipment.switch = 2 #主武器2         elif '3' == key.char:             c_equipment.switch = 3 #手q switch=3的时候不压q         elif '4' == key.char:             c_equipment.switch = 3 #刀具         elif '5' == key.char:             c_equipment.switch = 3 #手雷     except AttributeError:         if 'tab' == key.name:      #tab键异步操作检测             asyncHandle()         elif 'num_lock' == key.name:  #小键盘锁用来控制程序开关             changeOpen()         elif 'shift' == key.name:                c_contants.hold = False  2.3 pyautogui截屏 检测装备,首先要在打开装备栏的时候,截屏。  pyautogui.screenshot(region=[x, y, w, h])  x,y分别表示坐标,w,h表示宽度和高度。 截取之后,为了方便对比图片,需要将图片二值化,然后保存到本地。  完整代码如下:  import pyautogui  def adaptive_binarization(img):     #自适应二值化     maxval = 255     blockSize = 3     C = 5     img2 = cv2.adaptiveThreshold(img, maxval, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize, C)     return img2  # 屏幕截图 def shotCut(x, y, w, h):     im = pyautogui.screenshot(region=[x, y, w, h])     screen = cv2.cvtColor(numpy.asarray(im), cv2.COLOR_BGR2GRAY)     temp = adaptive_binarization(screen)     return temp      def saveScreen():     screen1 = shotCut(1780, 125, 614, 570)     cv2.imwrite("./resource/shotcut/screen.bmp", screen1)  2.4 素材准备 屏幕截图处理后如上,在装备识别之前,我们需要先准备很多素材图片用来对比。 比如:武器名、q托、握把、q口   武器名:   q托   2.5 裁剪图片 为了方便图片对比,我们需要将截取的装备栏部分的图片裁剪成和素材一样大小的图片。  比如,我们要检测武器一的名字:  #读取之前的截屏 screen = cv2.imread("./resource/shotcut/screen.bmp", 0) #裁剪出武器1名字 screenWepon1 = screen[0:40, 45:125] #拿裁剪的图片和武器素材的目录作为入参,进行对比 w1Name = compareAndGetName(screenWepon1, "./resource/guns/") 2.6 对比图片 #对比图片获取名字 def compareAndGetName(screenImg, dir):     #获取目录下所有文件     content = os.listdir(dir)     name = 'none'     max = 0     #遍历文件     for fileName in content:         #使用opencv读取文件         curWepone = cv2.imread(dir + fileName, 0)         #使用SSIM算法拿到图片相似度         res = calculate_ssim(numpy.asarray(screenImg), numpy.asarray(curWepone))         #获取相似度最大的         if max < res and res > 0.5:             max = res             name = str(fileName)[:-4]     return name  SSIM算法:  def calculate_ssim(img1, img2):     if not img1.shape == img2.shape:         raise ValueError('Input images must have the same dimensions.')     if img1.ndim == 2:         return ssim(img1, img2)     elif img1.ndim == 3:         if img1.shape[2] == 3:             ssims = []             for i in range(3):                 ssims.append(ssim(img1, img2))             return numpy.array(ssims).mean()         elif img1.shape[2] == 1:             return ssim(numpy.squeeze(img1), numpy.squeeze(img2))     else:         raise ValueError('Wrong input image dimensions.') 到这,我们就能获取到装备栏1位置的武器名字了。  2.7 操作鼠标 知道武器名字后,同理,我们可以获取到装备的配件。 然后,监听鼠标左键按下,然后开始下移鼠标。  我们以m762武器为例:  射速:86, 每一发子弹间隔86毫秒  后坐力: [42, 36, 36, 36, 42, 43, 42, 43, 54, 55, 54, 55, 54, 55, 54, 55, 62, 62, 62, 62, 62, 62, 62, 62,62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 77, 78, 77, 78]  表示每发子弹打出后,需要在y轴下移的距离,用来与后坐力对冲。  def moveMouse():      #从识别的数据中,再更具当前选择的武器,获取此刻的武器(比如按下1键,武器装备栏1为m762,那么此时武器就是m762)     curWepone = getCurrentWepone()     if (curWepone.name == 'none'):         return     #基础y轴补偿(没任何配件)     basic = curWepone.basic     #射速     speed = curWepone.speed     startTime = round(time.perf_counter(), 3) * 1000     for i in range(curWepone.maxBullets):         #是否可以开火,比如左键抬起,就中断。         if not canFire():             break         #系数,比如按住shift屏息,就需要再原来基础上乘1.33         holdK = 1.0         if c_contants.hold:             holdK = curWepone.hold         #乘以系数后实际的移动距离         moveSum = int(round(basic[i] * curWepone.k * holdK, 2))         while True:             if (moveSum > 10):                 #移动鼠标                 pydirectinput.move(xOffset=0, yOffset=10, relative=True)                 moveSum -= 10             elif (moveSum > 0):                 pydirectinput.move(xOffset=0, yOffset=moveSum, relative=True)                 moveSum = 0             elapsed = (round(time.perf_counter(), 3) * 1000 - startTime)             if not canFire() or elapsed > (i + 1) * speed + 10:                 break             time.sleep(0.01)  代码中的while循环:  其实再第一发子弹射出后,我们只需要下移42的距离,然后计算出需要等待的时间(0.086-移动鼠标的时间),然后第二发子弹射出,以此类推。  while循环的作用是防止屏幕抖动太厉害。因为直接移动42的距离,游戏中抖的厉害,所以我们再86毫秒的间隔里分了多次来移动鼠标。  python中的sleep函数不准确,所以我们要自己来计时,防止错过每发子弹的时间间隔。 不准确还有个好处,随机,正好不用自己来随机防止检测了。  三、最麻烦的部分 每个q的后坐力都不一样,我们需要自己去游戏的训练场,一发发子弹的调试,获取准确的补偿数据。  四、环境安装 https://blog.csdn.net/LookOutThe/article/details/131398983  五、最后 代码上传到gitee,感兴趣的一起交流。 https://gitee.com/lookoutthebush/PUBG ———————————————— 版权声明:本文为CSDN博主「七号公园的忧伤」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/LookOutThe/article/details/130639025 
  • [技术干货] Python期末复习题库——“Python”-转载
    1. (单选题)下列关于文件打开模式的说法,错误的是( C )。  A. r代表以只读方式打开文件  B. w代表以只写方式打开文件  C. a代表以二进制形式打开文件  D. 模式中使用+时,文件可读可写   2. (单选题)下列选项中,以追加模式打开文件的是( D ) A. a  B. ab+  C. a+  D. 以上全部  3. (单选题)下列哪个选项可以从文件中读取任意字节的内容?( A ) A. read()  B. readline()  C. readlines()  D. 以上全部  4. (单选题)下列选项中,不属于二进制文件的是( A )。 A. 文本文件 B. png文件 C. mp3文件 D. mp4文件  5. (单选题)执行下列语句: f = open('itheimA.txt', 'w') 打开文件的位置应该在( D )。 A. C盘根目录下 B. D盘根目录下 C. Python安装目录下 D. 与源文件相同的目录下  6. (单选题)计算 numpy 中元素个数的方法( B ) A. np.sqrt() B. np.size() C. np.identity() D. np.count()  7. (单选题)Numpy 中创建全为 0 的矩阵使用( A ) A. zeros B. ones C. empty D. arange  8. (单选题)numpy 中向量转成矩阵使用( A ) A. reshape B. reval C. arange D. random  9. (单选题)有数组 n = np.arange(24).reshape(2,-1,2,2),n.shape 的返回结果是什么?( A ) A. (2,3,2,2) B. (2,2,2,2) C. (2,4,2,2) D. (2,6,2,2)  10. (单选题)numpy包中,用来计算中位数的函数是:( B ) A. numpy.mean B. numpy.median C. numpy.var D. numpy.std  11. (单选题)numpy包中,求最大值的方法是:( A ) A. amax B. maxnum C. max D. big  12. (单选题)numpy中,random函数生成的数值在( C )之间 A. [0,1] B. (0,1) C. [0,1) D. (0,1]  13. (单选题)下面语句中pyplot是什么含义? ( A ) import matplotlib.pyplot as plt A. matplotlib的子库 B. matplotlib的子函数 C. matplotlib的类 D. matplotlib的方法  14. (单选题)使用哪个函数可以给坐标系增加横轴标签? ( A ) A. plt.xlabel("标签”) B. plt.label(x,"标签”) C. plt.label(y,"标签”) D. plt.ylabel("标签”)  15. (单选题)使用哪个函数可以给整个坐标系增加标题? ( C ) A. plt.text( ) B. plt.annotate( ) C. plt.title( ) D. plt.label( )  16. (单选题)plt.text0函数的作用是什么? ( C ) A. 给坐标轴增加题注 B. 在任意位置增加文本 C. 给坐标轴增加文本标签 D. 给坐标系增加标题  17. (单选题)下面哪个对matplotlib库的描述,哪个不正确? ( D ) A. matplotlib.pyplot是绘图的一种“快捷方式" B. matplotlib库是基于numpy库设计实现的 C. matplotlib是Python第三方数据展示库 D. matplotlib库展示的数据图无法输出为文件  18. (单选题)plt.xlabel('×坐标轴’,fontproperties='simHei',fontsize=20) ( B ) A. 设置坐标轴标签的大小 B. 设置坐标轴标签的字体,以正确显示中文 C. 设置坐标轴标签的颜色 D. 设置坐标轴标签的风格  19. (单选题)在pyplot子模块中创建画布的是下面哪个函数? ( A ) A. figure()  B. legend() C. subplots() D. random()  20. (单选题)绘制折线图的函数是下面哪个? ( B ) A. pyplot.scatter() B. pyplot.plot() C. pyplot.grid() D. pyplot.show()  21. (单选题)下面有关plt.show()和plt.imshow()的区别,说法正确的是: ( B ) A. 两者功能一模一样 B. imshow()接收一张图像,只是画出该图,并将图片写入你要放置的磁盘中。当imshow()函数的所有操作完毕之后,调用show()函数才会把图像显示出来 C. show()接收一张图像,只是画出该图,并将图片写入你要放置的磁盘中。 当show()函数的所有操作完毕之后,调用imshow()函数才会把图像显示出来。 D. imshow()功能包括了show()  22. (单选题)simhei 是指什么字体 ( D ) A. 宋体 B. 微软雅黑 C. 楷体 D. 黑体  23. (单选题)pyplot模块中显示图例的函数是哪个? ( A ) A. plt.legend() B. plt.show() C. plt.title() D. plt.plot()  24. (单选题)以下( A )是Python中文件的打开模式。  A. ab+ B. rt C. wt D. nb  25.(单选题)numpy 中矩阵转成向量使用( B )  A. Areshape  B. resize  C. arange  D. random  26. (单选题)numpy包中,计算标准差的函数是:( D ) A. numpy.mean B. numpy.median C. numpy.var D. numpy.std  27. (单选题)numpy中,用来生成主对角线上的元素全部为1,其他的元素全部为0的数组使用的是:( A ) A. ones B. zeros C. diag D. eye  28. (单选题)numpy中,生成服从均匀分布的随机数函数是:( B ) A. random B. rand C. randn D. randint  29. (单选题)numpy中,生成服从正态分布的随机数函数是:( C ) A. random B. rand C. randn D. randint  30. (单选题)numpy中,生成给定上下限范围的随机数函数是:( D ) A. random B. rand C. randn D. randint  31. (填空题)numpy中可以使用(   zeros  )函数来创建0 数组,使用(  ones )来创建全1数组。  32. (填空题)在numpy中,数组的排序主要有两种方式:直接排序和( 间接排序  )  33. (填空题)numpy中直接排序经常使用数组中的(  sort  )方法  34. (填空题)在numpy中,通过(   unique   )函数可以找出数组中的唯一值并返回已排序的结果,从而实现去除重复数据的功能  35. (填空题)在numpy中,可以使用tile与(  repeat  )实现数据重复若干次的操作。  36 (判断题)sort函数是最常见的排序方法,有返回值。( B ) A. 对 B. 错  37. (判断题)使用numpy库时,需要使用import进行导入。 ( A ) A. 对 B. 错  38. (判断题)检测数据缺失一般使用notnull 方法。( A ) A. 对 B. 错  39. (判断题)一个数组对象的itemsize,返回的值是由数组的大小决定的。 ( B ) A. 对 B. 错  40. (判断题)ufunc支持全部的四则运算,它的操作对象是数组。 ( A ) A. 对 B. 错  41. (填空题)文件的打开使用的是__open__方法。  42. (填空题)使用__with__语句可以实现close()方法的自动调用。  43. (填空题)在 Python 中__None__表示空类型。(英文首字母大写)  44. (填空题)字典中的键具有__唯一__性。  45. (填空题)布尔类型是一种特殊的__整型__。  46. (填空题)只有if条件表达式为__真__时才会执行满足条件的语句。  47. (多选题)下列创建子图的命令正确的有( ABD )。 A. plt.subplot(5,2,2)  B.plt.subplot(4,1,2)  C.plt.subplot(1011)  D. plt.subplot(10,1,1)  48. (多选题) 有二维列表ls=[[9,8],[7,6],[5,4],[3,2],[1,0]],则可以获得数字4的选项有( ABCD )。  A. ls[2][1] B. ls[2][-1] C. ls[-3][1] D. ls[-3][-1]  49. (多选题)以下关于Python分支的描述中,正确的是( BCD )。 A.Python分支结构使用保留字if、elif和else来实现,每个if后面必须有elif或else   B. if-else结构是可以嵌套的   C.if语句会判断if后面的逻辑表达式,当表达式为真时,执行if后续的语句块   D. 缩进是Python分***句的语法部分,缩进不正确会影响分支功能  50. (判断题)在一次打开和关闭操作之间,每调用一次write()方法,程序向文件中追加一行数据,并返回本次写入文件中的字节数。 ( A ) A. 对 B. 错  51. (判断题)使用文件时,如果不使用close方法关闭文件,一旦程序崩溃,很可能导致文件中的数据没有保存。 ( A ) A. 对 B. 错  52. (判断题)凡是打开的文件,切记要使用close方法关闭文件。 ( A ) A. 对 B. 错  53. (判断题)使用readline()每次可读取一行数据,假设本次读取了5行数据,下次打开文件时,readline()方法将会读取第6行数据。 ( B ) A. 对 B. 错  54. (判断题)CSV既可以作为一维数据的存储形式,亦可作为二维数据的存储形式。 ( A ) A. 对 B. 错  55. (判断题)数据可视化绘制图形的时候,需要先定义画布的大小。 ( A ) A. 对 B. 错  56. (判断题)数据可视化中,定义画布大小的函数是plot( B ) A. 对 B. 错  57. (判断题)数据可视化中,定义子图的函数是subplot(  A  ) A. 对 B. 错  58. (判断题)常用数据可视化的图表中,直方图的函数是hist(  A  ). A. 对 B. 错  59. (判断题)绘制饼图常用于表达数据的概率分布。( B ) A. 对 B. 错  60. (单选题) 最简单的 Series 是由( A )的数据构成  A.一个数组  B. 两个数组  C. 三个数组  D. 四个数组  61. (单选题)我们在使用 pandas时需要导入什么模块。 ( A ) A.import pandas as pd  B. import sys  C.import matplotlib  D. import pymysql  62. (单选题)利用(  B  )函数可以删除一列或者一行元素 A. delete B. drop C. clear D. cut  63.(单选题)pandas中的axis参数有两种取值,当它等于(  B  ) 时,可以删除列元素 A. 0 B. 1 C. -1 D. 缺省  64. (填空题)pandas有Series和 (DataFrame)两个数据结构。  65. (填空题)删除一列元素可以使用del命令,也可以使用(  pop  )函数  66. (判断题)在pandas中,标签索引不能使用切片 ( A ) A. 对 B. 错  67. (判断题)在pandas中,行索引不能使用切片 ( B ) A. 对 B. 错  68. (判断题)pandas中,在重新索引时如果某个索引值不存在,就会引入丢失索引值NaN。 ( A ) A. 对 B. 错  69. (判断题)层级索引是pandas的一项重要功能,它既可以是行索引,也可以是列索引。 ( A ) A. 对 B. 错  70. (判断题)Series只能通过索引和切片操作来获取单个或者多个元素。 ( B ) A. 对 B. 错  71. (判断题)DataFrame只能通过索引和切片操作来获取一行或者多行数据。 ( B ) A. 对 B. 错  72. (判断题)pandas是基于NumPy数组构建的。 ( A ) A. 对 B. 错  73. (单选题)脏数据是指(  D   )。 A. 污染的数据 B. 不规则的数据 C. 存在计算机内的数据 D. 异常值、缺失值  74. (单选题)pandas中提供了( A )函数用来识别缺失值。 A. isnull B. notnull C. null D. dropna  75. (单选题)下列哪种不是处理缺失值的方法(  C  ) A. 删除缺失值 B. 填充缺失值 C. 设置默认值 D. 利用插值法  76. (单选题)数据合并有( C )、主键合并和重叠合并三种。 A. 重复合并 B. 横向合并  C. 堆叠合并 D. 纵向合并  77. (单选题)pandas中提供了(   B   )函数来完成缺失值填充的功能。 A. fill B. fillna C. dropna D. interpolate  78. (填空题)数据重复有( 记录 )重复和( 特征 )重复两种。  79. (填空题)处理缺失值的填充法也称为( 替换法 )  80. (判断题)数据分析之前,除了要进行数据清洗之外,有时候也需要标准化数据。 ( A ) A. 对 B. 错  81. (判断题)异常值可以直接删除。 ( B ) A. 对 B. 错  82. (判断题)缺失值通常都是人为造成的。( B ) A. 对 B. 错  83. (单选题)根据文件的存储格式不同,可以分为( A )和二进制文件两种形式。 A. 文本文件 B. 数据文件 C. csv文件 D. 十进制文件  84. (单选题)使用Python的内置函数(  B  )方法可以打开指定文件并创建文件对象。 A. read B. open C. write D. readline  85. (单选题)读取文件的方法有( C )、readline、readlines等。 A. open B. redes C. read D. mode  86. (单选题)写文件的方法有(   C  )和writeline. A. open B. read C. write D. close  87. (单选题)( D )是一种轻量级的数据交换格式,Python标准库实现了对该格式的支持。 A. Excel B. word C. txt D. JSON  88. (单选题)修改数据的命令是( C )  A. select  B. insert into  C. updata  D. delect  89. (单选题)能删除行或列数据的命令是( D ) A. select B. pop C. update D. drop  90. (单选题)插入数据的命令是(  B   ) A. select B. insert into  C. update D. delete  91. (单选题)删除数据表的命令是( C ) A. select B. update C. drop table D. delete  92. (单选题)导入pymysql数据的命令是( C ) A. import database B. import SQL C. import pymysql D. pip install Mysql  93. (判断题)可用json.load方法来读取json格式文件。 ( A ) A. 对 B. 错 ———————————————— 版权声明:本文为CSDN博主「认真学习的小雅兰.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_74957752/article/details/130951660 
  • [专题汇总] 速进,一帖打尽2023年5月CodeArts板块技术干货合集贴。
     大家好,这个月给大家带来的是5月份codeArts板块技术干货合集贴分享。希望可以给大家带来帮助,快捷便利的获取到自己想要的技术干货。 1.centos下安装redis6.0.2方法及踩坑记录。 https://bbs.huaweicloud.com/forum/thread-0236120881445478099-1-1.html  2.64位MFC调用32位DLL https://bbs.huaweicloud.com/forum/thread-0228120819107276100-1-1.html  3.用js+html,全网最火build出爱心【转】 https://bbs.huaweicloud.com/forum/thread-0236120798795045092-1-1.html  4.Django权限系统auth模块用法解读【转】 https://bbs.huaweicloud.com/forum/thread-0248120796948452094-1-1.html  5.Django日志logging的配置和自定义添加方式【转】 https://bbs.huaweicloud.com/forum/thread-0248120796668399093-1-1.html  6.Django如何利用uwsgi和nginx修改代码自动重启【转】 https://bbs.huaweicloud.com/forum/thread-0228120794336186093-1-1.html  7.Python实现监控一个程序的运行情况【转】 https://bbs.huaweicloud.com/forum/thread-02115120793876180082-1-1.html  8.使用Python和Scrapy实现抓取网站数据【转】 https://bbs.huaweicloud.com/forum/thread-0243120793550271100-1-1.html  9.浅谈一下关于Python对XML的解析【转】 https://bbs.huaweicloud.com/forum/thread-0260120793358226074-1-1.html  10.如何用python多次调用exe文件运行不同的结果【转】 https://bbs.huaweicloud.com/forum/thread-0264120793008226093-1-1.html  11.django和vue互传图片并进行处理和展示【转】 https://bbs.huaweicloud.com/forum/thread-0228120792806281092-1-1.html  12.django python 获取当天日期的方法【转】 https://bbs.huaweicloud.com/forum/thread-0243120792719244099-1-1.html  13.python之关于数组和列表的区别及说明【转】 https://bbs.huaweicloud.com/forum/thread-0243120792501298098-1-1.html  14.python数组和矩阵的用法解读【转】 https://bbs.huaweicloud.com/forum/thread-0260120792197826073-1-1.html  15.Python利用wxPython实现长文本处理【转】 https://bbs.huaweicloud.com/forum/thread-02115120792101273081-1-1.html  16.django如何计算两个TimeField的时差【转】 https://bbs.huaweicloud.com/forum/thread-0236120792022558090-1-1.html      17.python连接kafka加载数据的项目实践【转】 https://bbs.huaweicloud.com/forum/thread-0243120791900417097-1-1.html  18.数据翻译——Easy_Trans的简单使用 https://bbs.huaweicloud.com/forum/thread-0236120706211297083-1-1.html  19.vue如何使用print-nb库来实现打印功能 https://bbs.huaweicloud.com/forum/thread-02115120450806805064-1-1.html  20.如何使用Vue.js来实现打印功能 https://bbs.huaweicloud.com/forum/thread-0264120450582740073-1-1.html  21.使用Java Cron表达式实现定时器 https://bbs.huaweicloud.com/forum/thread-0243120448768906076-1-1.html  22.JDK8 Stream 操作 https://bbs.huaweicloud.com/forum/thread-0248120389213456072-1-1.html  23.Springboot在有锁的情况下如何正确使用事务 https://bbs.huaweicloud.com/forum/thread-0228120388866643073-1-1.html  24.免费漂亮的Java图形验证码 https://bbs.huaweicloud.com/forum/thread-02115120388590161062-1-1.html  25.Vue-CLI 3.0中配置production gzip https://bbs.huaweicloud.com/forum/thread-02115120388359055061-1-1.html 
  • [技术干货] Django权限系统auth模块用法解读【转】
    认证系统auth auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理。auth可以和admin模块配合使用, 快速建立网站的管理系统。auth模块from django.contrib import authdjango.contrib.auth中提供了许多方法,这里主要介绍其中的三个:1 authenticate()   提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数如果认证信息有效,会返回一个  User  对象。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!!user = authenticate(username='someone',password='somepassword')2 login(HttpRequest, user)该函数接受一个HttpRequest对象,以及一个认证了的User对象此函数使用django的session框架给某个已认证的用户附加上session id等信息。from django.contrib.auth import authenticate, login def my_view(request):   username = request.POST['username']   password = request.POST['password']   user = authenticate(username=username, password=password)   if user is not None:     login(request, user)     # Redirect to a success page.     ...   else:     # Return an 'invalid login' error message.     ...3 logout(request) 注销用户from django.contrib.auth import logout def logout_view(request):   logout(request)   # Redirect to a success page.该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。4  is_authenticated()要求:1  用户登陆后才能访问某些页面,2  如果用户没有登录就访问该页面的话直接跳到登录页面3  用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址// 方法一 def my_view(request):   if not request.user.is_authenticated():     return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))# django已经为我们设计好了一个用于此种情况的装饰器:login_requier from django.contrib.auth.decorators import login_required @login_required def my_view(request):   ...若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递  当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。User对象User 对象属性:username, password(必填项)password用哈希算法保存到数据库is_staff : 用户是否拥有网站的管理权限.is_active : 是否允许用户登录, 设置为``False``,可以不用删除用户来禁止 用户登录is_authenticated()如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法很重要, 在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.nameUserUser是auth模块中维护用户信息的关系模式(继承了models.Model), 数据库中该表被命名为auth_user.User表的SQL描述:CREATE TABLE "auth_user" (     "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,      "password" varchar(128) NOT NULL, "last_login" datetime NULL,      "is_superuser" bool NOT NULL,      "first_name" varchar(30) NOT NULL,      "last_name" varchar(30) NOT NULL,     "email" varchar(254) NOT NULL,      "is_staff" bool NOT NULL,      "is_active" bool NOT NULL,     "date_joined" datetime NOT NULL,     "username" varchar(30) NOT NULL UNIQUE )User对象顾名思义即为表示用户的对象,里面的属性包括以上几条:创建好对象后,django会自动生成表,表名为auth_user,包含以上字段。具体的api文档如下所示:    class models.User     User 对象具有如下字段:     username     必选。少于等于30个字符。 用户名可以包含字母、数字、_、@、+、.和- 字符。     first_name     可选。 少于等于30个字符。     last_name     可选。少于30个字符。     email     可选。邮箱地址。     password     必选。 密码的哈希及元数据。(Django 不保存原始密码)。原始密码可以无限长而且可以包含任意字符。参见密码相关的文档。     groups     与Group 之间的多对多关系。     user_permissions     与Permission 之间的多对多关系。     is_staff     布尔值。指示用户是否可以访问Admin 站点。     is_active     布尔值。指示用户的账号是否激活。     is_superuser     布尔值。只是这个用户拥有所有的权限而不需要给他们分配明确的权限。     last_login     用户最后一次登录的时间。     date_joined     账户创建的时间。当账号创建时,默认设置为当前的date/time。auth模块提供了很多API管理用户信息, 在必要的时候我们可以导入User表进行操作, 比如其它表需要与User建立关联时.from django.contrib.auth.models import User认证用户先导入函数from django.contrib.auth import authenticate使用关键字参数传递账户和凭据:user = authenticate(username=username, password=password)认证用户的密码是否有效, 若有效则返回代表该用户的user对象, 若无效则返回None.该方法不检查is_active标志位.
  • [技术干货] Django日志logging的配置和自定义添加方式【转】
    一、日志的概念日志是一种可以追踪某些软件运行时所发生事件的方法。开发者可以在代码中调用日志记录相关的方法来表明发生了某些事情。一个事件可以用一个可包含可选变量数据的消息来描述,事件有严重性级别(level)。二、Django日志Django使用python内建的logging模块打印日志,logging配置由:记录器(Logger)、处理器(Handler)、过滤器(Filter)、格式化(Formatter)。1.logging模块默认定义了以下几个日志等级级别值描述CRITICAL/FATAL50关键错误/消息ERROR40错误WARNING30警告消息INFO20通知消息DEBUG10调试NOTSET0无级别日志等级:DEBUG < INFO < WARNING < ERROR < CRITICAL,而日志的信息量是依次减少的。当为某个应用程序指定一个日志级别后,应用程序会记录所有日志级别大于或等于指定日志级别的日志信息,而不是仅仅记录指定级别的日志信息。2. logging模块的使用方式介绍logging模块提供了两种记录日志的方式:第一种方式是使用logging提供的模块级别的函数第二种方式是使用Logging日志系统的四大组件logging所提供的模块级别的日志记录函数也是对logging日志系统相关类的封装而已。三、Logging提供的模块级别的函数函数说明logging.debug(msg, args, *kwargs)创建一条严重级别为DEBUG的日志记录logging.info(msg, args, *kwargs)创建一条严重级别为INFO的日志记录logging.warning(msg, args, *kwargs)创建一条严重级别为WARNING的日志记录logging.error(msg, args, *kwargs)创建一条严重级别为ERROR的日志记录logging.critical(msg, args, *kwargs)创建一条严重级别为CRITICAL的日志记录logging.log(level, args, *kwargs)创建一条严重级别为level的日志记录logging.basicConfig(**kwargs)对root logger进行一次性配置四、Logging日志模块四大组件组件名称对应类名功能描述记录器Logger提供了应用程序可一直使用的接口处理器Handler将logger创建的日志记录发送到合适的目的输出过滤器Filter提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录格式器Formatter决定日志记录的最终输出格式logging模块就是通过这些组件来完成日志处理的,logging模块级别的函数也是通过这些组件对应的类来实现的。这些组件之间的关系描述:记录器(logger)需要通过处理器(handler)将日志信息输出到目标位置,如:文件、sys.stdout、网络等;不同的处理器(handler)可以将日志输出到不同的位置;记录器(logger)可以设置多个处理器(handler)将同一条日志记录输出到不同的位置;每个处理器(handler)都可以设置自己的过滤器(filter)实现日志过滤,从而只保留感兴趣的日志;每个处理器(handler)都可以设置自己的格式器(formatter)实现同一条日志以不同的格式输出到不同的地方。简单点说就是:记录器(logger)是入口,真正干活儿的是处理器(handler),处理器(handler)还可以通过过滤器(filter)和格式器(formatter)对要输出的日志内容做过滤和格式化等处理操作。1.Logger日志记录器Logger 是日志系统的入口。每个 logger 都是命名了的 bucket, 消息写入 bucket 以便进一步处理。每一条写入 logger 的消息都是一条日志记录。每一条日志记录也包含日志级别,代表对应消息的严重程度。日志记录还包含有用的元数据,来描述被记录的事件细节。当 logger 处理一条消息时,会将自己的日志级别和这条消息的日志级别做对比。如果消息的日志级别匹配或者高于 logger 的日志级别,它就会被进一步处理。否则这条消息就会被忽略掉。当 logger 确定了一条消息需要处理之后,会把它传给 Handler。Django内置记录器类类功能描述django.request 请求处理相关的日志消息。5xx响应被提升为错误消息;4xx响应被提升为警告消息。django.server由RunServer命令调用的服务器所接收的请求的处理相关的日志消息。HTTP 5XX响应被记录为错误消息,4XX响应被记录为警告消息,其他一切都被记录为INFO。django.template与模板呈现相关的日志消息django.db.backends有关代码与数据库交互的消息。例如,请求执行的每个应用程序级SQL语句都在调试级别记录到此记录器2.logging处理器类名功能描述logging.StreamHandler类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息logging.FileHandler将日志消息写入文件filename。logging.handlers.DatagramHandler(host,port) 发送日志消息给位于制定host和port上的UDP服务器。使用UDP协议,将日志信息发送到网络logging.handlers.HTTPHandler(host, url) 使用HTTP的GET或POST方法将日志消息上传到一台HTTP 服务器。logging.handlers.RotatingFileHandler(filename)将日志消息写入文件filename。如果文件的大小超出maxBytes制定的值,那么它将被备份为filenamel。logging.handlers.SocketHandler使用TCP协议,将日志信息发送到网络。logging.handlers.SysLogHandler日志输出到sysloglogging.handlers.NTEventLogHandler远程输出日志到Windows NT/2000/XP的事件日志logging.handlers.SMTPHandler远程输出日志到邮件地址logging.handlers.MemoryHandler日志输出到内存中的制定buffer3.Filter过滤器在日志从 logger 传到 handler 的过程中,使用 Filter 来做额外的控制。默认情况下,只要级别匹配,任何日志消息都会被处理。不过,也可以通过添加 filter 来给日志处理的过程增加额外条件。例如,可以添加一个 filter 只允许某个特定来源的 ERROR 消息输出。Filter 还被用来在日志输出之前对日志记录做修改。例如,可以写一个 filter,当满足一定条件时,把日志记录从 ERROR 降到 WARNING 级别。Filter 在 logger 和 handler 中都可以添加;多个 filter 可以链接起来使用,来做多重过滤操作。4.Formatter格式器日志记录最终是需要以文本来呈现的。Formatter 描述了文本的格式。一个 formatter 通常由包含 LogRecord attributes 的 Python 格式化字符串组成,不过你也可以为特定的格式来配置自定义的 formatter。格式描述%(name)s记录器 logger 的名字%(levelno)s数据形式的日志记录级别%(levelname)s文本形式的日志记录级别%(filename)s执行日志记录调用的源文件的文件名%(pathname)s执行日志记录调用的源文件的 全路径+文件名%(funcName)s执行日志记录调用的函数名称%(module)s调用的模块名称,django是 app 的名称%(lineno)d记录调用的行号%(created)s执行日志记录的时间%(asctime)s日期时间%(msecs)s毫秒部分%(thread)s线程ID%(threadName)s线程名称%(process)d进程ID%(message)s记录的消息,自定义内容五、Django中添加logging1.在项目setting.py 文件中配置logginger 日志# 日志配置 # 给ADMINS发送邮件需要配置 ADMINS = (     ('admin_name', 'your@gmail.com'), ) MANAGERS = ADMINS # 创建log文件的文件夹 LOG_DIR = os.path.join(BASE_DIR, "logs") # 基本配置,可以复用的 LOGGING = {     "version": 1,     "disable_existing_loggers": False,     "filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}},     "formatters": {  # 定义了两种日志格式         "verbose": {  # 标准             "format": "%(levelname)s %(asctime)s %(module)s "             "%(process)d %(thread)d %(message)s"         },         'simple': {  # 简单             'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'         },     },     "handlers": {  # 定义了三种日志处理方式         "mail_admins": {  # 只有debug=False且Error级别以上发邮件给admin             "level": "ERROR",             "filters": ["require_debug_false"],             "class": "django.utils.log.AdminEmailHandler",         },         'file': {  # Info级别以上保存到日志文件             'level': 'INFO',             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,根据文件大小自动切             'filename': os.path.join(LOG_DIR, "info.log"),  # 日志文件             'maxBytes': 1024 * 1024 * 10,  # 日志大小 10M             'backupCount': 2,  # 备份数为 2             'formatter': 'simple',  # 简单格式             'encoding': 'utf-8',         },         "console": {  # 打印到终端console             "level": "DEBUG",             "class": "logging.StreamHandler",             "formatter": "verbose",         },     },     "root": {"level": "INFO", "handlers": ["console"]},     "loggers": {         "django.request": {  # Django的request发生error会自动记录             "handlers": ["mail_admins"],             "level": "ERROR",             "propagate": True,  # 向不向更高级别的logger传递         },         "django.security.DisallowedHost": {  # 对于不在 ALLOWED_HOSTS 中的请求不发送报错邮件             "level": "ERROR",             "handlers": ["console", "mail_admins"],             "propagate": True,         },                 }, }
  • [技术干货] Django如何利用uwsgi和nginx修改代码自动重启【转】
    利用uwsgi和nginx修改代码自动重启在默认设置下,uwsgi本身不会立即加载修改后的文件。nginx + uwsgi + django 部署的站点,如果修改了py代码,需要重新启动 uwsgi 才会生效。如果有需要 Django 代码改动时立即生效,可以在启动 uwsgi 的 ini 的配置文件里加入参数py-autoreload = 1 ( 写在 ini 配置文件中,记得一定要 = 1,否则不生效)。py-autoreload = 1    完整配置feiublog.ini[uwsgi] socket = 127.0.0.1:9090 stats = 127.0.0.1:9191 chdir = /var/project/feiublog wsgi-file =/var/project/feiublog/wsgi.py pidfile = /var/project/feiublog/uwsgi_blog.pid touch-reload = /var/project/feiublog/uwsgi_blog.pid buffer-size = 32768 processes = 1 workers= 2 threads = 2 daemonize = /tmp/log/uwsgi_blog.log py-autoreload = 1  # 代码修改后自动重启正确手动重载uwsgi和代码的方式使用命令uwsgi feiublog.ini即可自动生成pidfile文件的uswgi_blog.pidpidfile = /var/project/feiublog/uwsgi_blog.pid然后在你的uwsgi.pid的目录下执行:uwsgi --reload uwsgi_blog.pid其中uwsgi_blog.pid即进程的pid文件。至此,修改后的代码即可自动重载生效Django修改文件后不生效 重启uwsgi解决问题描述这里主要是在线上环境,我们上传代码后,发现没有生效。因为会生成.pyc文件。解决办法# 关闭所有 uwsgi进程,发现通过uwsgi --roload ****.pid 不一定有用 killall -9 uwsgi # 启动 uwsgi uwsgi --ini /home/wwwroot/laoji.org/uwsgi.ini  # 重启一下nginx service nginx reload
  • [技术干货] Python实现监控一个程序的运行情况【转】
    一、前言在使用selenium库爬取一些小东西,经常出现程序进入死循环的情况。导致一个简简单单的需求,居然花了3天没跑完,很是气愤。遂给写了一个监听程序,当爬虫死机一定时间的时候,就把这只爬虫拍死,然后根据日志从上次爬的地方重启一只新爬虫。二、使用psutil库和subprocess库介绍当涉及到与操作系统进行交互的时候,Python中的 psutil 和 subprocess 库都是非常有用的工具。1.psutil 库psutil(process and system utilities)是一个跨平台的库,提供了许多有用的系统和进程信息。通过 psutil 库,我们可以轻松地获取操作系统的各种信息,如 CPU 使用情况、内存使用情况、磁盘使用情况等等。此外,psutil 还可以用于获取和操作进程信息,如获取进程的 CPU 使用情况、内存使用情况、打开的文件和网络连接等等。以下是 psutil 库的一些主要功能:获取 CPU 使用率、内存使用率、磁盘使用情况、网络信息等等。获取系统启动时间、用户数、主机名等等系统信息。获取进程的 PID、CPU 使用情况、内存使用情况、线程数等等信息。操作进程,如发送信号、终止进程等等。2.subprocess 库subprocess 库是用于在 Python 程序中执行外部命令的标准库。通过 subprocess 库,我们可以启动一个子进程来执行外部命令,然后在 Python 程序中捕获并处理该命令的输出。subprocess 库提供了多个函数,如 Popen、call、check_call 等等,以便于我们执行外部命令和处理命令的输出。以下是 subprocess 库的一些主要功能:启动子进程并执行外部命令。在子进程中捕获并处理命令的输出。设置子进程的环境变量、工作目录等等属性。通过管道连接多个子进程,从而实现数据流的处理。总之,psutil 和 subprocess 是 Python 中非常有用的库,可以帮助我们轻松地获取和操作系统和进程的各种信息,以及执行外部命令和处理命令的输出。在编写需要与操作系统进行交互的 Python 程序时,这两个库是不可或缺的。三、使用psutil库和subprocess库示例程序要监控一个程序的运行情况并在需要时将其杀死并重启,可以使用 Python 的 psutil 模块来实现。psutil 模块可以访问系统进程和系统资源的信息,并提供了一些操作系统的 API 接口。具体来说,我们可以使用 psutil 模块来获取程序的 PID(进程ID),并在需要时将进程杀死并重启。下面是一个简单的示例,演示了如何使用 psutil 模块监控程序的运行情况,并在需要时将进程杀死并重启: import psutil import subprocess import time  # 启动程序 p = subprocess.Popen(['python', 'your_program.py'])  while True:     # 检查程序是否在运行     if psutil.pid_exists(p.pid) and psutil.pid_exists(p.pid) in psutil.pids():         # 如果程序在运行,等待一段时间后再检查         time.sleep(5)     else:         # 如果程序已经退出,重启程序         p = subprocess.Popen(['python', 'your_program.py']) 在这个示例中,我们首先使用 subprocess.Popen() 启动程序,并获取程序的 PID。然后在一个无限循环中,不断检查程序是否在运行。如果程序在运行,我们会等待一段时间后再检查。如果程序已经退出,我们就使用 subprocess.Popen() 重新启动程序。这样,即使程序崩溃了,也能够在很短的时间内重新启动。需要注意的是,在监控程序运行情况时,要确保程序出现异常不会导致系统崩溃或造成严重影响。如果程序出现无限循环、内存泄漏等问题,监控程序可能只会让问题变得更加严重。因此,在编写监控程序时,要确保程序本身是健壮的,并且程序出现异常时能够正确地退出。另外,要注意不要在监控程序中占用过多的系统资源,以免影响其他程序的正常运行。四、多进程通信在 Python 中,可以使用 multiprocessing 库来实现不同进程之间的交互。multiprocessing 是 Python 标准库中的一个模块,它允许我们启动并发进程,以便于同时执行多个任务。在这里,由于需求不是很复杂,我用了一个取巧的方法,就是用一个txt文件当作中介,也可以了理解为池子,程序往里面丢日志。然后重启的时候根据日志也就是爬到第几个了,断点重续。下面程序功能是:当程序imgico.py50s不更新的时候,重启。 import psutil import subprocess import time # 启动程序 p = subprocess.Popen(['python', 'imgico.py']) preendNum=2 count=0 while True:     # 检查程序是否在运行     time.sleep(5)     if psutil.pid_exists(p.pid) and psutil.pid_exists(p.pid) in psutil.pids():         # 如果程序在运行,等待一段时间后再检查         time.sleep(5)     else:         # 如果程序已经退出,重启程序         p = subprocess.Popen(['python', 'imgico.py','--begin',str(endNum)])     with open('cache.txt', 'r', encoding='utf-8') as f:         lines = f.readlines()         if len(lines)==0:             endNum=2         endNum = lines[len(lines) - 1].replace('\n', '')      if preendNum==endNum:         count+=1     else:         preendNum = endNum         count=0     if count==10:         print('重启一次!'+str(count))         p = subprocess.Popen(['python', 'imgico.py', '--begin', str(endNum)])         count=0 
  • [技术干货] 使用Python和Scrapy实现抓取网站数据【转】
    在本文中,我们将介绍如何使用Python的Scrapy库进行网站数据抓取。Scrapy是一个功能强大的网络爬虫框架,允许开发者轻松地抓取和解析网站内容。一、安装Scrapy首先,您需要安装Scrapy。这可以通过以下命令完成:pip install scrapy二、创建一个Scrapy项目接下来,我们需要创建一个Scrapy项目。在命令行中运行以下命令:scrapy startproject myproject这将创建一个名为myproject的新目录,其中包含Scrapy项目的基本结构。三、定义一个Scrapy爬虫在Scrapy项目中,爬虫是用于抓取和解析网页的主要组件。要创建一个新的爬虫,请在myproject/spiders目录下创建一个名为example_spider.py的文件,并输入以下代码: import scrapy  class ExampleSpider(scrapy.Spider):     name = 'example'     start_urls = ['http://example.com']      def parse(self, response):         self.log('Visited %s' % response.url)         for quote in response.css('div.quote'):             item = {                 'author_name': quote.css('span.text::text').extract_first(),                 'author_url': quote.css('span a::attr(href)').extract_first(),             }             yield item 在这个例子中,我们定义了一个名为ExampleSpider的新爬虫类,它继承自scrapy.Spider。我们为爬虫指定了一个唯一的名称example,以及一个起始URL(http://example.com)。parse()方法是Scrapy用于处理下载的网页的回调函数。在这个方法中,我们使用CSS选择器从页面中提取相关数据,并将其保存为字典。四、运行Scrapy爬虫要运行Scrapy爬虫,请在命令行中导航到项目目录,然后运行以下命令:scrapy crawl example这将启动爬虫,并开始从起始URL抓取数据。抓取的数据将以日志形式显示在控制台中。五、保存抓取的数据Scrapy允许您将抓取的数据保存为各种格式,如CSV、JSON和XML。要将数据保存为JSON文件,请运行以下命令:scrapy crawl example -o output.json这将抓取的数据保存到名为output.json的文件中。六、遵守网站的robots.txtScrapy默认遵守网站的robots.txt文件中的规则。robots.txt是网站管理员用来指示网络爬虫如何抓取网站内容的文件。您可以通过在Scrapy项目的settings.py文件中设置ROBOTSTXT_OBEY选项来禁用此功能:ROBOTSTXT_OBEY =False请注意,禁用robots.txt遵守可能导致您的爬虫被网站封禁。在进行网络抓取时,请始终遵守网站的抓取策略,并尊重网站所有者的意愿。七、设置下载延迟为了避免对目标网站造成过大的压力,您可以设置下载延迟。在Scrapy项目的settings.py文件中设置DOWNLOAD_DELAY选项:DOWNLOAD_DELAY = 2这将导致Scrapy在下载连续两个页面之间等待2秒。八、使用中间件和管道Scrapy提供了中间件和管道功能,让您可以在抓取过程中执行自定义操作。中间件允许您在请求发送和响应接收过程中执行操作,例如设置代理、处理重定向等。管道则允许您在处理抓取到的数据项时执行操作,例如去重、存储到数据库等。要使用中间件和管道,您需要在Scrapy项目的settings.py文件中添加相应的配置,并编写自定义的中间件和管道类。九、结论Scrapy是一个强大的Python网络抓取框架,可帮助您轻松地抓取和解析网站数据。通过遵循本教程,您应该已经掌握了如何使用Scrapy创建和运行简单的爬虫。要了解更多关于Scrapy的高级用法,请参阅官方文档,也可关注我后续发文。
总条数:2474 到第 页
上滑加载中