pip install -U huggingface_hub
export HF_ENDPOINT=https://hf-mirror.com
$env:HF_ENDPOINT = "https://hf-mirror.com"
huggingface-cli download --resume-download gpt2 --local-dir gpt2
部分要token的还是自己老老实实去登陆原站吧,这种方式只能用在普通的模型上面。
物联网相关的应用、开发资讯,IoT智能装置和云端结合的技术研究,新鲜事物的分享。
pip install -U huggingface_hub
export HF_ENDPOINT=https://hf-mirror.com
$env:HF_ENDPOINT = "https://hf-mirror.com"
huggingface-cli download --resume-download gpt2 --local-dir gpt2
部分要token的还是自己老老实实去登陆原站吧,这种方式只能用在普通的模型上面。
传统的真机Python+pip部署方式早已被淘汰了。
而venv虚拟部署的方式还有很多人在用,也确实比传统真机部署好很多,但也再被渐渐淘汰。
目前较为流行的一种模式是:Conda+UV的组合方式。
conda:核心是环境管理工具,负责创建隔离的虚拟环境(可包含不同 Python 版本、系统级依赖甚至非 Python 包,如 C 库)。
uv:核心是Python 包管理器,专注于快速安装 / 管理 Python 包(类似 pip,但速度更快、依赖解析更高效),本身不管理环境,而是依赖于当前激活的 Python 环境。
建议在激活 conda 环境后安装 uv,避免全局安装导致的环境混淆。
pip install uv
uv的使用例子:
uv pip install transformers==4.24.0 # 安装指定版本
uv pip uninstall jieba # 卸载包
uv sync # 同步依赖(根据 pyproject.toml 或 requirements.txt)
注意事项(避免潜在问题):
1、不混用 conda 和 uv 安装同一 Python 包
例如,不要用 conda install pandas 后再用 uv pip install pandas,可能导致版本冲突(conda 和 pip/uv 管理的包路径虽然一致,但依赖解析逻辑不同)。
transformers、jieba);numpy、opencv,conda 会自动安装对应的 C 库)。2、uv 不处理非 Python 依赖
uv 仅负责 Python 包,若包依赖系统级库(如 libssl、libffi),仍需通过 conda 或系统包管理器(apt)安装:
# 例如安装需要系统库的包,先用 conda 安装依赖 conda install -c conda-forge libsndfile # 安装音频处理的系统库 uv pip install soundfile # 再用 uv 安装依赖该库的 Python 包
3、环境迁移时需同步两者的配置
若要复制 conda 环境,除了用 conda env export,还需同步 uv/pip 管理的包(通过 uv pip freeze > requirements.txt 导出)。
uv 和 conda 是互补工具:conda 负责环境隔离和系统级依赖,uv 负责高效管理 Python 包,在 conda 环境中使用 uv 不仅安全,还能显著提升包安装速度,推荐结合使用。
国内使用建议:
/.config/uv/uv.toml
index-url = “https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple”
另外,uv也是可以直接运行py文件的。如图所示。

在游戏开发领域,引人入胜的对话系统和精彩的叙事常常能为游戏增色不少,成为吸引玩家深入体验的关键因素。而 Dialogic 2,正是一款专为游戏开发者打造的强大插件,能助力开发者轻松实现复杂且生动的游戏对话与叙事。

Dialogic 2 基于 Godot 引擎开发,对 Godot 4.2 及以上版本提供良好支持。其核心功能极为丰富,为开发者打开了创意的大门。它的对话系统堪称一绝,允许开发者创建复杂的对话树。无论是分支剧情、条件判断,还是多角色同时参与的对话,都能轻松实现。想象一下,在角色扮演游戏中,玩家的不同选择通过对话分支引发截然不同的剧情走向,这无疑大大增强了游戏的重玩性与趣味性。
Godot下载地址:
https://godotengine.org/download
对于视觉小说类游戏开发,Dialogic 2 更是得心应手。通过简单直观的拖放操作,开发者就能快速搭建起视觉小说场景,灵活管理背景、角色立绘以及对话框等元素,让文字与画面完美融合,构建出引人入胜的故事世界。此外,它还提供了便捷的角色管理功能,开发者可以方便地设定角色的各项属性、状态和行为,使角色在游戏中更加鲜活立体。
值得一提的是,Dialogic 2 内置了自动更新功能。这意味着开发者无需手动操心繁琐的更新事宜,插件会自动保持在最新版本,及时享受新功能与修复的漏洞,极大地提升了开发效率与稳定性。同时,Dialogic 2 采用单元测试确保代码质量,利用 gdUnit4 测试框架,开发者可在本地运行测试,为代码的可靠性保驾护航。
从应用场景来看,Dialogic 2 的适用性十分广泛。在视觉小说游戏开发中,它能快速构建起整个游戏架构,管理对话、角色和场景,使开发者专注于故事创作。在角色扮演游戏里,其丰富的对话系统可以支持多角色互动,创造出丰富多彩的剧情分支,为玩家带来沉浸式体验。冒险游戏通过它管理对话和角色,增强玩家代入感;教育游戏借助其对话与叙事功能,实现互动式学习体验,寓教于乐。
总的来说,Dialogic 2 以其易于使用的特性、强大的功能、自动化更新以及活跃的开源社区支持,成为游戏开发者打造精彩游戏对话与叙事的不二之选。无论你是经验丰富的行业老手,还是初涉游戏开发领域的新手,Dialogic 2 都能为你的游戏开发之旅增添助力,让你的创意通过精彩的对话与叙事完美呈现。
一、安装与激活
Dialogic 2 要求 Godot 4.2 或更高版本。确认已安装合适版本后,按以下步骤安装插件:
Dialogic 2插件下载地址:
https://github.com/dialogic-godot/dialogic/releases
二、认识编辑器界面
成功安装并激活插件后,在 Godot 编辑器顶部会出现一个新的Dialogic标签页(位于2D、3D、脚本和资源库旁边)。点击进入,映入眼帘的是 Dialogic 主界面。界面顶部能看到 Dialogic 的不同编辑器选项;左侧边栏会展示最近使用过的角色和时间线;右上角有几个常用功能按钮,分别是添加时间线、添加角色、参考管理器和播放时间线 。
三、创建时间线
时间线用于编排游戏中的对话流程等事件,创建步骤如下:
四、创建角色
为游戏创建角色的步骤如下:
五、为游戏添加对话
extends Node2D
func _ready():
Dialogic.start('ExampleDialog')
通过以上步骤,你就能利用 Dialogic 2 插件在 Godot 游戏中搭建起基础的对话系统。随着对插件的深入使用,你还可探索其更多高级功能,如条件判断、多角色同时对话、对话分支剧情等,从而打造出更丰富精彩的游戏体验。
1. 硬件准备
2. 硬件连接
3. MicroPython编程
machine库,控制GPIO引脚输出高低电平,控制MOSFET的导通和截止。示例代码:
from machine import Pin
import time
fire_pin = Pin(15, Pin.OUT) # 点火引脚,连接到MOSFET栅极
def fire():
fire_pin.value(1) # 开启加热
print("Heating...")
def stop_fire():
fire_pin.value(0) # 关闭加热
print("Stop Heating.")
while True:
input_value = input("Enter '1' to heat, '0' to stop: ")
if input_value == '1':
fire()
elif input_value == '0':
stop_fire()
else:
print("Invalid input.")
4. 安全注意事项
5. 补充说明
在中国内地,由于网络环境的特殊性,使用Gradle构建Android APK时,经常会遇到依赖下载缓慢或失败的问题。配置SOCKS代理确实是解决这一问题的有效方法之一。以下是一些关于如何为Java和Gradle添加SOCKS代理,以帮助您顺利构建APK的信息:
1. Gradle代理配置
.gradle文件夹中找到或创建一个gradle.properties文件。systemProp.socks.proxyHost=your_socks_hostsystemProp.socks.proxyPort=your_socks_portsystemProp.java.net.socks.username=your_socks_username (如果需要)systemProp.java.net.socks.password=your_socks_password (如果需要)your_socks_host、your_socks_port、your_socks_username和your_socks_password替换为您的SOCKS代理服务器的相应信息。nonProxyHosts属性也非常重要,它可以指定不需要通过代理访问的主机。2. Java代理配置
-D参数来设置这些属性。例如:
-DsocksProxyHost=your_socks_host-DsocksProxyPort=your_socks_portgradle.properties文件中配置代理更为方便。3. 解决常见问题
总结
通过正确配置SOCKS代理,您可以显著提高Gradle在中国内地构建APK的成功率。建议您仔细检查代理设置,并根据您的网络环境进行调整。
HTTPS可以防止传输过程中数据被偷看,但无法阻止客户端本地的攻击。比如Json之类的文件,如果完全明文,可能会让一些黑客看到敏感信息。
是否可以对其进行一层简单的加密?
以Python为例子,用一个加密库就可以。
首先执行:pip install cryptography
然后开始编写如下代码。
from cryptography.fernet import Fernet
import json
# 生成密钥
key = Fernet.generate_key()
cipher_suite = Fernet(key)
# JSON 数据
data = {
"name": "Alice",
"age": 30,
"city": "Wonderland"
}
# 将 JSON 数据转换为字符串
json_data = json.dumps(data)
# 加密 JSON 数据
encrypted_data = cipher_suite.encrypt(json_data.encode())
print("加密后的数据:", encrypted_data)
print("密钥:", key)
它会输出:
加密后的数据: b’gAAAAABmraTSlRWANyVFWRKm4CgjpoJEhyLID-ri64K3RP2yItbM-4POPid1dVh_1mWVItoSzZy-bPC_pObCCDUJ-ktuxWbi5zAcSn8VDrTiYiyqwXWvygLcBHmwToapDEDoqA6RjHQs_WeOCKAZqPnge5Q-J4xNpw==’
密钥: b’MvHuTCwAj3SNz93MZtI_1Ww_tHn9XVUFxyARGyGLTxQ=’
要解密的时候怎么办呢?
from cryptography.fernet import Fernet
import json
daa = b'gAAAAABmraTSlRWANyVFWRKm4CgjpoJEhyLID-ri64K3RP2yItbM-4POPid1dVh_1mWVItoSzZy-bPC_pObCCDUJ-ktuxWbi5zAcSn8VDrTiYiyqwXWvygLcBHmwToapDEDoqA6RjHQs_WeOCKAZqPnge5Q-J4xNpw=='
key = b'MvHuTCwAj3SNz93MZtI_1Ww_tHn9XVUFxyARGyGLTxQ='
decrypted_data = cipher_suite.decrypt(daa).decode()
json_data = json.loads(decrypted_data)
print(json_data)
它会输出:
{‘name’: ‘Alice’, ‘age’: 30, ‘city’: ‘Wonderland’}
以上代码使用了 Fernet 加密算法,这是对称加密的一种实现。Fernet 是一种基于 AES(高级加密标准) 的加密方案,具体来说,它使用 AES-128 在 CBC(密码分组链接)模式 下进行加密,并结合 PKCS7 填充 和 HMAC(基于哈希的消息认证码) 来确保数据的完整性和保密性。
在密码学史中,恩尼格玛密码机(Enigma)是一种具有影响力的加密与解密文件密码机。该密码机采用了一系列相似的转子机械加解密机制,为对称加密算法的流加密奠定了基础。
恩尼格玛密码机外观看起来是一个装满了复杂而精致元件的盒子。然而,当我们打开它时,可以将其分解为相对简单的几个部分。最核心的部分包括键盘、显示器和三个转子。键盘用于输入明文,显示器则用于显示加密后的密文。三个转子负责将明文转换为密文的过程。

在恩尼格玛密码机中,当按下键盘上的某个键时,与该字母对应的密文会在显示器上亮起。这是因为转子内部集成了6条线路(在实物中是26条),可以将键盘的信号对应到显示器不同的小灯上去。例如,如果按下字母’a’键,灯’B’就会亮起,这意味着字母’a’被加密成了字母’B’。

为了提高加密的复杂性,恩尼格玛密码机还采用了三个转子的旋转机制。每个转子都可以独立旋转,并具有26个不同的位置。当输入一个字母时,转子会旋转一定的角度,使得相同的字母在加密时对应不同的密文。这种机制增加了破译的难度,使得恩尼格玛密码机在二战期间成为了一种难以破解的加密工具。
此外,为了使消息更难以破译,恩尼格玛密码机还采用了空格和标点符号的省略机制。这意味着在加密过程中,空格和标点符号不会被包括在内,从而使得密文更难以被解读。
总体而言,恩尼格玛密码机的工作原理是通过键盘输入明文,经过三个转子的转换和加密算法的处理,最终在显示器上显示密文。这种加密方式具有很高的复杂性和难以破解的特点,因此在密码学史上具有重要的地位。
然而,尽管恩尼格玛密码机在二战期间被广泛使用并被认为是安全的加密工具,但在二战末期,英国的密码学家通过不懈的努力成功地破解了恩尼格玛密码机。这一事件成为了密码学史上的一个重要里程碑,也为我们提供了一个宝贵的教训:随着技术的发展和进步,没有任何一种加密方式是绝对安全的。
下面用C语言来实现这个加密过程,代码比较简单,仅供参考。可自己完善。
先来一段明文:Send troops to Poland today(今日出兵波兰),中间空格要去掉。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAX_CHARS 26
// 交换两个字符
void swap(char *a, char *b) {
char temp = *a;
*a = *b;
*b = temp;
}
// 随机打乱字符数组
void shuffle(char *arr, int n) {
for (int i = n - 1; i > 0; i--) {
int j = rand() % (i + 1);
swap(&arr[i], &arr[j]);
}
}
int main() {
// 生成字母表
char a[MAX_CHARS];
for (int i = 0; i < MAX_CHARS; i++) {
a[i] = 'a' + i;
}
// 复制并打乱字母表
char b[MAX_CHARS];
memcpy(b, a, MAX_CHARS);
shuffle(b, MAX_CHARS);
// 建立对应密码表 (这里使用数组代替字典,下标作为索引)
char dict[MAX_CHARS][2];
for (int i = 0; i < MAX_CHARS; i++) {
dict[i][0] = a[i];
dict[i][1] = b[i];
}
// 待加密字符串
char word[] = "sendtroopstopolandtoday";
char encrypted[MAX_CHARS];
printf("加密前: %s\n", word);
// 加密
int j;
for (int i = 0; i < strlen(word); i++) {
for (j = 0; j < MAX_CHARS; j++) {
if (word[i] == dict[j][0]) {
encrypted[i] = dict[j][1];
break;
}
}
}
encrypted[strlen(word)] = '\0';
printf("加密后: %s\n", encrypted);
return 0;
}
结果是:
加密前: sendtroopstopolandtoday
加密后: dgncsuffjdsfjfylncsfclr
先别高兴太早,这只是单张表,很容易被破解。
为了提升破解者的难度,下面用两张表来混合加密。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAX_CHARS 26
// 交换两个字符
void swap(char *a, char *b) {
char temp = *a;
*a = *b;
*b = temp;
}
// 随机打乱字符数组
void shuffle(char *arr, int n) {
for (int i = n - 1; i > 0; i--) {
int j = rand() % (i + 1);
swap(&arr[i], &arr[j]);
}
}
int main() {
// 初始化随机数种子
srand(time(NULL));
// 生成字母表
char a[MAX_CHARS];
for (int i = 0; i < MAX_CHARS; i++) {
a[i] = 'a' + i;
}
// 复制并打乱字母表两次
char b[MAX_CHARS], c[MAX_CHARS];
memcpy(b, a, MAX_CHARS);
memcpy(c, a, MAX_CHARS);
shuffle(b, MAX_CHARS);
shuffle(c, MAX_CHARS);
// 建立对应密码表 (使用二维数组表示)
char dict1[MAX_CHARS][2], dict2[MAX_CHARS][2];
for (int i = 0; i < MAX_CHARS; i++) {
dict1[i][0] = a[i];
dict1[i][1] = b[i];
dict2[i][0] = a[i];
dict2[i][1] = c[i];
}
// 待加密字符串
char word[] = "sendtroopstopolandtoday";
char encrypted[100]; // 确保足够大
printf("加密前: %s\n", word);
// 加密
int j;
for (int i = 0; i < strlen(word); i++) {
for (j = 0; j < MAX_CHARS; j++) {
if (word[i] == dict1[j][0]) {
encrypted[i] = i % 2 == 0 ? dict1[j][1] : dict2[j][1];
break;
}
}
}
encrypted[strlen(word)] = '\0';
printf("加密后: %s\n", encrypted);
return 0;
}
结果是:
加密前: sendtroopstopolandtoday
加密后: yazkownmfuomfmiqzkomhqx
双表混合法,即第一个字符是使用第一个映射表加密,第二个字符使用第二张映射表来进行加密,这可以使加密的安全度提高很多,也比较接近Enigma机的工作原理。
下面来讲明文的还原方式。
根据前面获得的两张映射表,将它们全部反转。
第一张表:
{‘a’: ‘s’, ‘b’: ‘t’, ‘c’: ‘r’, ‘d’: ‘h’, ‘e’: ‘b’, ‘f’: ‘w’, ‘g’: ‘q’, ‘h’: ‘j’, ‘i’: ‘p’, ‘j’: ‘e’, ‘k’: ‘v’, ‘l’: ‘i’, ‘m’: ‘g’, ‘n’: ‘z’, ‘o’: ‘n’, ‘p’: ‘f’, ‘q’: ‘m’, ‘r’: ‘u’, ‘s’: ‘y’, ‘t’: ‘o’, ‘u’: ‘d’, ‘v’: ‘c’, ‘w’: ‘l’, ‘x’: ‘a’, ‘y’: ‘x’, ‘z’: ‘k’}
第二张表:
{‘a’: ‘q’, ‘b’: ‘l’, ‘c’: ‘g’, ‘d’: ‘k’, ‘e’: ‘a’, ‘f’: ‘v’, ‘g’: ‘j’, ‘h’: ‘y’, ‘i’: ‘p’, ‘j’: ‘z’, ‘k’: ‘x’, ‘l’: ‘n’, ‘m’: ‘c’, ‘n’: ‘d’, ‘o’: ‘m’, ‘p’: ‘t’, ‘q’: ‘s’, ‘r’: ‘w’, ‘s’: ‘u’, ‘t’: ‘h’, ‘u’: ‘o’, ‘v’: ‘f’, ‘w’: ‘b’, ‘x’: ‘e’, ‘y’: ‘r’, ‘z’: ‘i’}
反转第一张表:
{‘s’: ‘a’, ‘t’: ‘b’, ‘r’: ‘c’, ‘h’: ‘d’, ‘b’: ‘e’, ‘w’: ‘f’, ‘q’: ‘g’, ‘j’: ‘h’, ‘p’: ‘i’, ‘e’: ‘j’, ‘v’: ‘k’, ‘i’: ‘l’, ‘g’: ‘m’, ‘z’: ‘n’, ‘n’: ‘o’, ‘f’: ‘p’, ‘m’: ‘q’, ‘u’: ‘r’, ‘y’: ‘s’, ‘o’: ‘t’, ‘d’: ‘u’, ‘c’: ‘v’, ‘l’: ‘w’, ‘a’: ‘x’, ‘x’: ‘y’, ‘k’: ‘z’}
反转第二张表:
{‘q’: ‘a’, ‘l’: ‘b’, ‘g’: ‘c’, ‘k’: ‘d’, ‘a’: ‘e’, ‘v’: ‘f’, ‘j’: ‘g’, ‘y’: ‘h’, ‘p’: ‘i’, ‘z’: ‘j’, ‘x’: ‘k’, ‘n’: ‘l’, ‘c’: ‘m’, ‘d’: ‘n’, ‘m’: ‘o’, ‘t’: ‘p’, ‘s’: ‘q’, ‘w’: ‘r’, ‘u’: ‘s’, ‘h’: ‘t’, ‘o’: ‘u’, ‘f’: ‘v’, ‘b’: ‘w’, ‘e’: ‘x’, ‘r’: ‘y’, ‘i’: ‘z’}
然后把密文填进去,就可以出来明文了。
这里还是用代码来实现:
#include <stdio.h>
#include <string.h>
int main() {
char mm[] = "yazkownmfuomfmiqzkomhqx";
char dict3[26][2] = {
{'s', 'a'}, {'t', 'b'}, {'r', 'c'}, {'h', 'd'}, {'b', 'e'}, {'w', 'f'}, {'q', 'g'}, {'j', 'h'}, {'p', 'i'}, {'e', 'j'},
{'v', 'k'}, {'i', 'l'}, {'g', 'm'}, {'z', 'n'}, {'n', 'o'}, {'f', 'p'}, {'m', 'q'}, {'u', 'r'}, {'y', 's'}, {'o', 't'},
{'d', 'u'}, {'c', 'v'}, {'l', 'w'}, {'a', 'x'}, {'x', 'y'}, {'k', 'z'}
};
char dict4[26][2] = {
{'q', 'a'}, {'l', 'b'}, {'g', 'c'}, {'k', 'd'}, {'a', 'e'}, {'v', 'f'}, {'j', 'g'}, {'y', 'h'}, {'p', 'i'}, {'z', 'j'},
{'x', 'k'}, {'n', 'l'}, {'c', 'm'}, {'d', 'n'}, {'m', 'o'}, {'t', 'p'}, {'s', 'q'}, {'w', 'r'}, {'u', 's'}, {'h', 't'},
{'o', 'u'}, {'f', 'v'}, {'b', 'w'}, {'e', 'x'}, {'r', 'y'}, {'i', 'z'}
};
char word[strlen(mm) + 1];
word[strlen(mm)] = '\0';
for (int i = 0; i < strlen(mm); i++) {
if (i % 2 == 0) {
for (int j = 0; j < 26; j++) {
if (mm[i] == dict3[j][0]) {
word[i] = dict3[j][1];
break;
}
}
} else {
for (int j = 0; j < 26; j++) {
if (mm[i] == dict4[j][0]) {
word[i] = dict4[j][1];
break;
}
}
}
}
printf("明文是:%s\n", word);
return 0;
}
明文是:sendtroopstopolandtoday
实际的Enigma机工作起来要比这个复杂很多,但基本原理类似。有兴趣的朋友可以深入研究。
如果你曾经想在 Raspberry Pi 5 上尝试神经网络、人工智能和机器学习的世界,树莓派这次推出了官方AI 套件。该 AI 套件是与 Hailo 合作开发的,它可将本地高效的推理能力,集成到各种应用程序中。现已上架 Raspberry Pi 的经销商网络,价格 70 美元。

Raspberry Pi AI 套件拆解
Raspberry Pi AI 套件包括我们的 M.2 HAT+ 和 Hailo-8L AI 加速器模块。AI 套件安装在 Raspberry Pi 5 上,可让你快速构建复杂的 AI 视觉应用程序,实时运行。具有低延迟和低功耗要求。用于对象检测、语义和实例分割、姿态估计和面部识别(仅举几例)的先进神经网络完全在 Hailo-8L 协处理器上运行,使 Raspberry Pi 5 CPU 可以自由地执行其它任务。
Raspberry Pi AI 套件的主要功能包括:

搭载AI Kit的树莓派5
Hailo创建了一个庞大的模型库,用户可以在这里找到各种各样的预训练神经网络模型,可以在AI Kit上部署和优化。
地址:
https://github.com/hailo-ai/hailo_model_zoo/tree/master/docs/public_models/HAILO8L
软件方面
最新版本的 Raspberry Pi OS 会自动检测 Hailo 模块,因此操作系统和利用该模块的应用程序可以立即使用它。rpicam-apps 套件现在有一个后处理模板,用于在摄像头管道中集成实时运行的神经网络推理。
“通过使用预安装的 Hailo Tappas 后处理库,仅几百行 C++ 代码就能创建基于 AI 的高级应用程序。类似级别的集成到我们的 Picamera2 框架中很快就会实现。”
除了可以在 rpicam-apps 或 Picamera2 中使用 Hailo-8L 协处理器外。Raspberry Pi AI Kit 中还打包了集成在 GStreamer 框架和本地 Python 或 C/C++ 应用程序中的 API。包括非摄像机用例,例如在预先录制的视频文件上运行推理。

近看Hailo模块
软件安装步骤非常简单。通过apt安装几个软件包,重新启动,你就可以在几分钟内尝试我们的一些AI演示。完整的说明可以在我们的入门指南中找到。下面是我们的一些演示的预览,你可以通过rpicam-apps运行。
详细步骤:
https://www.raspberrypi.com/documentation/accessories/ai-kit.html#getting-started
有了树莓派AI Kit,你不但可以在picam-apps或Picamera2中使用Hailo-8L协处理器。树莓派还打包了一个集成在GStreamer框架和本地Python或C/C++应用程序中的API。这包括非相机用例,例如在预先录制的视频文件上运行推理。
DrissionPage是一个基于Python的网页自动化库,它结合了selenium和requests的优点,可以轻松实现网页的自动化操作。DrissionPage的主要特点是其简洁的API设计,使得用户可以很容易地编写代码来实现网页自动化。
安装DrissionPage非常简单,只需要通过pip安装即可:
pip install drissionpage
初始化
在使用DrissionPage之前,需要先进行初始化。可以使用以下代码进行初始化:
from DrissionPage import MixPage
page = MixPage(‘chrome’)
这里我们使用Chrome浏览器进行初始化,你也可以使用其他浏览器,例如Firefox。
打开网页
初始化之后,可以使用open_url方法来打开一个网页。
例如,我们可以使用以下代码来打开百度首页:
page.open_url(‘https://www.baidu.com’)
查找元素
在打开网页之后,我们通常需要查找网页中的元素。DrissionPage提供了多种方法来查找元素,例如ele、eles、css、xpath等。例如,我们可以使用以下代码来查找百度首页的搜索框:
search_box = page.ele(‘#kw’)
这里我们使用ele方法来查找id为kw的元素。
操作元素
在找到元素之后,我们可以对元素进行各种操作,例如输入文本、点击等。例如,我们可以使用以下代码来在百度搜索框中输入文本并搜索:
search_box.send_keys(‘Python’)
page.ele(‘#su’).click()
这里我们使用send_keys方法来输入文本,使用click方法来点击搜索按钮。
获取元素信息
在找到元素之后,我们还可以获取元素的各种信息,例如文本、属性等。例如,我们可以使用以下代码来获取百度搜索结果的第一条结果的标题:
title = page.ele(‘.t a’).text
print(title)
此外,DrissionPage支持复杂的网页交互,例如填写表单、点击按钮等:
# 填写表单
browser.find_element_by_name(‘username’).send_keys(‘my_username’)
browser.find_element_by_name(‘password’).send_keys(‘my_password’)
# 点击登录按钮
browser.find_element_by_xpath(‘//button[@type=”submit”]’).click()
DrissionPage可以用于各种网页操作,下面是一些常见的使用示例:
# 处理下拉菜单
browser.find_element_by_id(‘dropdown’).click()
browser.find_element_by_xpath(‘//option[@value=”option-value”]’).click()
# 滚动到页面底部
browser.scroll_to_bottom()
# 获取当前页面的URL
current_url = browser.get_current_url()
# 下拉刷新
page.execute_script(‘window.scrollTo(0, document.body.scrollHeight)’)
# 上传文件
upload_button = page.ele(‘#upload’)
upload_button.send_keys(‘path/to/your/file’)
DrissionPage的工作原理非常简单。它首先使用requests库来请求网页,然后使用selenium库来加载网页。在加载网页之后,就可以使用selenium的方法来查找元素、操作元素等。
DrissionPage还支持多窗口和多标签页操作、自定义等待、处理JavaScript弹窗等高级功能:
切换到新的标签页
browser.open_new_tab()
自定义等待
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
wait = WebDriverWait(page.driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, ‘some_id’)))
这里我们使用selenium的WebDriverWait和expected_conditions来实现自定义等待。
处理JavaScript弹窗
page.driver.switch_to.alert.accept()
这里我们使用switch_to.alert.accept()来处理JavaScript弹窗。
DrissionPage是一个功能强大且易于使用的Python库,它简化了网页自动化操作,使得即使是编程新手也能快速上手。通过本文的介绍,相信你已经对DrissionPage有了基本的了解,并且能够开始使用它来完成你的网络爬虫项目。