作者归档:Dasmz

Debian/Ubuntu系统下,配置并使用SFTP,分用户分目录

前缀、文档修改记录

20251009 初始化编辑此文章,完稿

章节1、需求描述

Debian/Ubuntu的Linux系统内,SFTP权限分配问题,用户user1 可以访问 /data/user1 路径和 /data/share路径, 用户user2可以访问/data/user2和/data/share路径,这样,每个用户可以拥有自己独立的存储目录,也可以有共享的目录访问权限

章节2、环境描述

今日的测试环境 Debian 12的1台Linux服务器,作为文件服务器,/data目录有做完软RAID后的500GB空间,基本不怕丢失文件的哦。

典型的 SFTP 用户目录权限隔离 + 共享目录权限设计

user1 只能访问 /data/user1 和 /data/share
user2 只能访问 /data/user2 和 /data/share
两个用户互相不能访问对方的私有目录
/data/share 为公共共享目录(权限:可读写)
最安全和推荐的方法是使用 sshd_config 配置 SFTP Chroot Jail,然后利用 Bind Mount 来挂载共享目录。

用 Chroot 限制 SFTP 用户的根目录;
用组(group)控制共享目录访问;
调整目录权限(chmod / chown);
修改 SSH 配置来限定 SFTP 行为。

章节3、配置过程,独享目录+共享目录(可读写)

// 创建 Chroot 根目录,创建用户实际数据目录,设置 chroot 目录权限(必须由 root 拥有且不可写)

mkdir -p /sftp/user1
mkdir -p /sftp/user2

mkdir -p /data/user1
mkdir -p /data/user2
mkdir -p /data/share

chown root:root /sftp/user1 /sftp/user2
chmod 755 /sftp/user1 /sftp/user2

配置 sshd,实现 chroot jail,编辑 SSH 配置文件 /etc/ssh/sshd_config , 注释掉默认的 Subsystem 行,使该行语法失效。

# Subsystem sftp /usr/lib/openssh/sftp-server

移动到文件末尾,增加相关配置,增加sftp用户组sftp_users的配置,禁止登录系统,仅允许sftp

# 使用内部 sftp-server 实现 Chroot 功能
Subsystem sftp internal-sftp

# 为 SFTP 用户定义匹配组
Match Group sftp_users
    # 强制使用 internal-sftp
    ForceCommand internal-sftp
    # 禁止 TTY 和 X11 转发
    PermitTTY no
    X11Forwarding no
    # 设置 Chroot 根目录,%h 会被替换为用户的主目录
    ChrootDirectory %h
    # 允许用户的主目录内有读写权限
    AllowTcpForwarding no

注释:这里的 %h 是一个变量,它将使用 /etc/passwd 中定义的用户主目录(Home Directory)

继续配置,在系统里增加用户的组,创建不同用户并设置主目录和组

groupadd sftp_users

useradd -m -d /sftp/user1 -s /sbin/nologin -g sftp_users user1
passwd user1

useradd -m -d /sftp/user2 -s /sbin/nologin -g sftp_users user2
passwd user2

chown user1:sftp_users /data/user1
chown user2:sftp_users /data/user2
chmod 700 /data/user1
chmod 700 /data/user2

chown root:sftp_users /data/share
chmod 770 /data/share

注释:用户的 Home 目录必须设置为 Chroot Jail 的根目录

参数 -m: 创建用户主目录(即 /sftp/user1)

参数 -d /sftp/user1: 指定主目录为 Chroot 根目录

参数 -s /sbin/nologin: 禁止用户通过 SSH 登录 Shell,只能进行 SFTP

设置 Bind Mount 挂载点,在每个用户的 Chroot 根目录下创建挂载点(目标目录),将实际数据目录挂载到 Chroot 内部的入口

mkdir /sftp/user1/user1_files
mkdir /sftp/user1/share

mount --bind /data/user1 /sftp/user1/user1_files
mount --bind /data/share /sftp/user1/share

mkdir /sftp/user2/user2_files
mkdir /sftp/user2/share

mount --bind /data/user2 /sftp/user2/user2_files
mount --bind /data/share /sftp/user2/share

编辑 /etc/fstab 文件,使挂载在系统重启后仍然生效,编辑/etc/fstab 中添加以下四行

/data/user1      /sftp/user1/user1_files  none bind 0 0
/data/share      /sftp/user1/share        none bind 0 0

/data/user2      /sftp/user2/user2_files  none bind 0 0
/data/share      /sftp/user2/share        none bind 0 0

设置目录权限,需要确保用户对实际数据目录有正确的读写权限,设置用户私有目录的权限

chown user1:user1 /data/user1
chmod 700 /data/user1

chown user2:user2 /data/user2
chmod 700 /data/user2

设置共享目录的权限

groupadd sftp_users
usermod -aG sftp_users user1
usermod -aG sftp_users user2

# 设置 /data/share 目录
chown root:sftp_users /data/share
chmod 770 /data/share 

重启服务并测试

systemctl restart sshd

注释:用户登录后,其 SFTP 根目录就是 /sftp/userN,他们将只能看到 userN_filesshare 目录

章节4、配置过程,增加只读的共享目录

只读共享目录 /data/iso , 里面放的一些iso文件,这个一般用户,只读即可。

创建目录,并设置权限: 设置它为 root 拥有且不可写。

mkdir -p /data/iso

chown root:sftp_users /data/iso
chmod 750 /data/iso                  # 确保所有用户可读、可执行(进入目录)

在 Chroot 内部创建挂载点

mkdir /sftp/user1/iso_ro
mkdir /sftp/user2/iso_ro

执行只读 Bind Mount

systemctl daemon-reload
mount --bind /data/iso /sftp/user1/iso_ro -o ro
mount --bind /data/iso /sftp/user2/iso_ro -o ro

持久化 Bind Mount(系统重启后仍然生效),编辑 /etc/fstab 文件,添加以下两行

/data/iso      /sftp/user1/iso_ro       none bind,ro 0 0
/data/iso      /sftp/user2/iso_ro       none bind,ro 0 0

注释:bind,ro 确保了挂载的持久性和只读属性

总结:

私有目录 (/data/user1, /data/user2):通过 chown 和 chmod 700 实现独占读写。

共享目录 (/data/share):通过 sftp_share 组和 chmod 2770 实现组内读写。

只读目录 (/data/iso):通过 mount --bind -o ro 实现只读访问。

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

通过公网服务器映射家里的nextcloud的webdav

前缀、文档修改记录

20251006 初始化编辑此文章,完稿,暂未解决,求助
20251008 更新文档

章节1、需求描述

家中服务器

运行 Nextcloud (Docker),没有公网 IP,通过 frpc(TCP 模式) 将 80 端口映射到公网服务器

公网服务器

运行 frps,部署 nginx + HTTPS 证书,nginx 对外暴露的是 HTTPS,nginx 反代到 frp 转发来的 nextcloud HTTP

现象:

Web(浏览器)访问正常nextcloud。WebDAV 的 HTTPS 访问(例如通过 https://nas.mydomain.com/remote.php/dav/files/...)不通。

章节2、故障排查1 – Nginx反代的时候,少了对webdav的参数支持

WebDAV 不仅用 GET / POST,还会用 PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK,这些方法如果被 nginx 屏蔽或未转发,会直接导致 WebDAV 客户端报错(例如 Windows 或 macOS Finder 会直接显示“连接失败”)。

proxy_methods 指令,因为那是 第三方模块(ngx_http_proxy_methods_module) 的语法,不在标准版 nginx 中。

只要不写 proxy_methods 和 limit_except,nginx 默认会转发所有 HTTP 方法,包括 PROPFIND。

那我这个错误,应该不是这个因素导致的。

章节3、 故障排查2 – Nextcloud的配置文件

我配置文件的路径是,/data/config/config.php,确保反代后返回的链接是 HTTPS。

指定信任来源: trusted_proxies 参数是一个数组,用于明确列出 Nextcloud 应该信任的 反向代理服务器的 IP 地址 或 IP 地址段(CIDR 格式)。

正确配置 trusted_proxies 后,Nextcloud 才能从反向代理设置的特定 HTTP 头(默认为 X-Forwarded-For)中提取出真正的 客户端 IP 地址

  'trusted_proxies' => 
  array (
    0 => '192.168.1.10', // 你的反向代理服务器的 IPv4 地址
    1 => '2001:db8::1',  // IPv6 地址示例
    2 => '172.16.0.0/12',// IP 地址段 (CIDR) 示例,例如 Docker 网络的范围
  ),
  // ... 其他配置 ...

'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'https://nas.mydomain.com',

在这个参数中,增加我服务器的域名,增加服务器的IP,重启一下docker/nextcloud实例。

章节4、故障排查3 – frp的TCP多路复用

启用 TCP 多路复用,应该在配置文件中,tcp_mux = true , 不过,我这里frp 0.65.0 版本

# tcp_mux = true  # 默认就是 true,可以不写

章节5、故障排查4 – nextcloud的应用密码

Nextcloud 的 WebDAV 默认不接受普通用户密码(如果开启了双重认证、OIDC、或 brute-force protection)。

在 Nextcloud 网页端:

点击右上角头像 → “安全”; 在“设备与会话”→“创建新应用密码”; 复制生成的密码

增加了,尝试,也没有用,应该也不是这个问题。

章节6、故障排查5 – nginx的配置

对于nginx,增加http2的配置,我这里版本是1.28.0,HTTP/2 是这样启用的

listen 443 ssl;
http2 on;

完全兼容 HTTP/1.1 回退,增加上来。尴尬,也没啥用。

章节7、故障排查6 – frp的参数

我这里配的frp,走的TCP,这个可能是不对的,frps和frpc之间的tcp通道是经过TLS加密的,这样的话,可能是存在TLS in TLS的情况。

如果是这样的情况,那就直接先docker重新拉一个纯HTTP方式的nextcloud容器看看,直接映射用ftp的TCP方式映射本地的http去公网试试。

用纯HTTP倒是没啥问题。

章节8、故障排查7 – 修改注册表

Windows 需要修改注册表才能支持非微软 WebDAV 服务器

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters]
“BasicAuthLevel”=dword:00000002

0 禁用基本认证

1 只允许 HTTPS 基本认证

2 允许 HTTP/HTTPS 基本认证(推荐至少为 1)
net stop WebClient
net start WebClient

章节9、故障排查8 – 配置架构变化

从原先的
家中服务器:运行 Nextcloud (Docker),没有公网 IP,通过 frpc(TCP 模式) 将 80 端口映射到公网服务器
公网服务器:运行 frps,部署 nginx + HTTPS 证书,nginx 对外暴露的是 HTTPS,nginx 反代到 frp 转发来的 nextcloud HTTP

调整为
家中服务器:运行 Nextcloud (Docker)/TCP/80,没有公网 IP,通过加载证书的Nginx反代本地80到本机的TCP/SSL/443,通过 frpc(TCP 模式) 将 443 端口映射到公网服务器
公网服务器:运行 frps,通过刚刚frpc上指定的TCP/SSL/公网端口访问

即相当与HTTPS 场景的直通配置(TLS passthrough),避免经过frp隧道的时候的TLS in TLS的问题,这个也是我一开始怀疑的点。

章节10、故障排查9 – 测试 WebDAV 端点(不带认证)

curl -i http://localhost/remote.php/dav/

表示 WebDAV 接口存在,只是需要登录。

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

Windows 11 系统,挂载SAMBA报错

前缀、文档修改记录

20251002 初始化编辑此文章,完稿

章节1、需求描述

Windows 11系统,挂载Linux的SAMBA,但是错误提示为“A specified logon session does not exist. It may already have been terminated.”

错误的原因是这次安装的Windows 11 系统很新,有的安全设置等级高,需要修改一下。

章节2、 修改方式

2.1 修改步骤1

打开控制面板。

点击 程序 → 启用或关闭 Windows 功能。

在列表中找到并勾选 “SMB 1.0/CIFS 文件共享支持”。

2.2 修改步骤2

按下 Win + R 键打开“运行”对话框,输入 secpol.msc 并按回车,打开本地安全策略。

导航到:本地策略 → 安全选项。

在右侧找到并双击设置项:“网络安全: LAN 管理器身份验证级别”(Network security: LAN Manager authentication level)。

将其值修改为:“发送 LM 和 NTLM – 使用 NTLMv2 会话安全(如果协商)”

2.3 重启一下系统,即可。

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

把整个物理笔记本的系统塞进Proxmox VE虚拟化

前缀、文档修改记录

20250909 初始化编辑此文章,完稿
20250911 更新内容

章节1、需求描述

一直想把公司配发的电脑,整个硬盘上的系统(含系统盘、数据盘)整个打包,塞进虚拟化里面,这样方便自己有的时候,临时出差用一下公司的内网。

章节2、Disk2vhd工具

使用到的是微软官方的Disk2vhd工具,用它,可以把整个磁盘,全部打包成vhd

https://learn.microsoft.com/en-us/sysinternals/downloads/disk2vhd

章节3、操作过程

3.1、 (可选)镜像复制整个磁盘

我弄了2个NVMe的移动硬盘盒,把工作笔记本电脑的三星固态M2/512GB 硬盘拆了出来,用 Linux系统的 dd命令,拿一块国产的M2/512GB,整个镜像了一遍磁盘,后续的操作可以在我复制出来的这块国产M2/512GB的磁盘上操作,即便操作步骤有错误,也不会把工作系统弄炸裂。

3.2、 运行disk2vhd工具

disk2vhd工具支持对运行中的系统中执行,同样也支持移动硬盘,比如我刚刚镜像出来的国产化硬盘M2/512GB,只要移动硬盘里的分区能够在 Windows 中正常挂载并显示为卷(例如有盘符 D:\、E:\),Disk2vhd 就能扫描并列出来,你也可以勾选它来进行转换。

选项1、 [勾选] prepare for use in virtual PC

选项2、 [不需要]use vhdx

因为我最终要把镜像文件弄到我的Proxmox VE环境中,vhd格式是适合的,而你们若准备用HyperV承载,则这里应该选择vhdx

选项3、 [不需要]usse volumn shadow copy

因为,我是用的其他电脑,运行disk2vhd,移动硬盘里,是需要打包成vhd的工作系统,基于 Windows 的卷影复制服务(VSS, Volume Snapshot Service)来创建 VHD,这个选项,我这里不必。

VHD File name: 存储路径,我的台式机的HDD/D盘,剩余可用磁盘空间759GB,足够放置这个512GB的磁盘文件。

点击 Create,即可开始,因为是逐块读取磁盘和写入的,速度一般不会很快,慢慢等待执行完成就是。

3.3、 上传文件

将刚刚生成的 DESKTOP-XXYYZZ.vhd文件上传到我的PVE磁盘目录下,注意因为文件比较大,传输完成后,用md5sum/sha1sum之类的校验一下完整性。

3.4、 格式转换

PVE 中新建一台虚拟机

硬件参数设置尽量和实体机一致(CPU、磁盘控制器、UEFI/BIOS 模式)

转换为 PVE 可用格式

qemu-img convert -f vpc -O qcow2 DESKTOP-XXYYZZ.vhd vm-101-disk-0.qcow2

// 其中-f表示原始file式,QEMU recognizes vpc for VHD files and vhdx for VHDX files.   qemu-img info /var/lib/vz/template/iso/DESKTOP-AAU5KV1.VHD
// 其中vmid-101 这个101根据你们实际的虚拟机ID来。VM 配置文件里挂载


qm importdisk 102 /root/vm-101-disk-0.qcow2 local-zfs
// 其中102这个修改为你创建的VM的ID号
// local-zfs修改为你的存储路径
创建虚拟机(CPU/MEM/noDisk/noSystemISO/网卡E1000),网卡MAC地址跟公司的网卡的一致。

BIOS/UEFI 设置要和实体机一致(Windows 10/11 大概率用 UEFI + OVMF)。

硬盘控制器先选 SATA(这样可以保证先能启动)。

网卡先用 Intel E1000(Windows 自带驱动)。

把转换好的磁盘文件挂载到这台 VM 上(替换掉空磁盘)

章节3、 可能的驱动问题

Windows 迁移后可能蓝屏,要提前装好 virtio 驱动

https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

alist 程序安装配置使用手册

前缀、文档修改记录

20250901 初始化编辑此文章,完稿

章节1、需求描述

有的时候,需要一个简单临时使用的web化的文件存储,这个时候,可以试试看 alist这个程序。

章节2、alist简介

Alist是一个支持多种存储后端的单体文件列表程序,Go 语言生态,可以将本地文件夹、网盘(如阿里云盘、百度网盘、OneDrive、Google Drive 等)映射,方便管理和分享。
特点:支持多种存储驱动、界面简洁、跨平台(Windows、Linux、Mac、Docker)、API 丰富,可对接其他应用

章节3、风险预警

alist开源项目,在2025年6月左右,经历了一次所有权变更,更偏向“商业化”发展的道路了,个人使用注意隐私安全。

“Alist 项目可能已经被转让给一家名为不够科技(贵州)的公司。从提交的 PR 内容来看,购买方疑似在项目中加入了用于收集用户操作系统信息的代码“ 新闻链接新浪

章节4、配置使用alist软件

项目程序下载地址 https://github.com/AlistGo/alist/releases

如果像我一样,只需要在云主机上使用alist最简单的本地云盘功能,且为了安全,则选择项目变动前的发布版本 v3.45

下载对应系统的压缩包(如 alist-linux-amd64.tar.gz)

解压后进入目录,运行:

./alist server

首次运行会生成配置文件,并显示默认管理员账号密码

就可以通过你服务器的公网IP地址 http://IP:5244/ 即可访问到网页,用户名 admin / A1qqyd4V密码看前面运行的日志。

进入之后,在主页的底边上,有一个 [管理] 选项,点击并进入,做如下设置,进行挂载本次存储器:

存储 –> 添加 –> 本机存储,然后填写 [挂载路径] 和 [根文件夹路径],之后保存就完成了基本的设置。

挂载路径(Mount Path),这是你在 Alist 网盘中访问的路径。

举例:如果你填 /movies,那么在 Alist 里打开 /movies 就会显示对应的本地文件夹内容,类似“映射目录到虚拟盘的别名”。

根文件夹路径(Root Folder Path),这是 你服务器/本机上实际的文件路径。

举例:如果你想把 /home/username/Downloads 映射到 Alist,那就填写 /home/username/Downloads。Windows 下例如 D:\Video。

配置完这个本地存储,点击全部重新加载。点击左下角的首页即可。

创建几个文件测试一下





另外,还可以在 [用户] 选项中创建一些低权限账户,供局域网中其它设备访问。

章节5、Docker方式部署(这个不推荐,因为没必要)

拉取镜像

docker pull xhofe/alist:latest

创建容器

docker run -d \
  --name=alist \
  -p 5244:5244 \
  -v /etc/alist:/opt/alist/data \
  xhofe/alist:latest

浏览器访问 http://服务器IP:5244 即可进入管理界面

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

Linux系统环境中,动态扩容ext4文件系统分区

前缀、文档修改记录

20250706 初始化编辑此文章,完稿

章节1、需求描述

日常在用云主机的过程,常见的是将一个云硬盘的容量使用满了,可以从云厂家侧购买扩容的云硬盘容量,比如原先操作系统的数据盘是500G,可以扩容为1000G。本篇介绍,在云厂家扩容好硬盘后,我们如何在操作系统内部应用购买的磁盘容量到数据盘分区/dev/vdb1。

章节2、模拟环境描述

操作系统: Debian 12

操作命令: parted 等

磁盘: /dev/sdb 5GB , 扩容为 /dev/sdb 10GB, 容量全部在/dev/sdb1分区,文件系统ext4

章节3、操作步骤

3.1、安装常用工具

root@Server:~# apt install parted lvm2

3.2、查看需要调整容量的磁盘的当前状态

root@Server:~# df -h       // 查看该硬盘目前的磁盘使用率
...
/dev/sdb1                    4.9G   24K  4.6G   1% /data
...
root@Server:~# parted /dev/sdb print      // 查看该硬盘目前的分区情况,记录当前分区起始位置,结束位置信息。
Partition Table: gpt
...
Number  Start   End     Size    File system  Name  Flags
 1      1049kB  5368MB  5367MB  ext4         DATA
...

3.3、启动 parted 工具进行/dev/sdb1的动态扩容

在确保云主机厂家页面上,扩容好磁盘容量后,进行主机或者对应硬盘的快照,或者有数据备份后,再执行本操作,数据无价。

为了演示,我给原先/dev/sdb 5GB扩容到了 /dev/sdb 10GB大小。

root@Server:~# parted /dev/sdb
GNU Parted 3.5
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) rm 1    // 删除分区表项不会清除文件系统或数据,只是移除指针。
(parted) mkpart primary ext4 1049kB 100%    // 创建新的分区,起始位置与旧分区相同,结束位置设为磁盘末尾,GPT分区系统,基本都可以是主primary分区
(parted) quit  

3.4、刷新分区表

root@Server:~# partprobe /dev/sdb
root@Server:~# 

3.5、扩展文件系统

root@Server:~# resize2fs /dev/sdb1
resize2fs 1.47.0 (5-Feb-2023)
Filesystem at /dev/sdb1 is mounted on /data; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/sdb1 is now 2620928 (4k) blocks long.

root@Server:~# 

可以看到 /dev/sdb1 9.8GB … /data ,已经成功扩容磁盘的剩余容量到当前的分区上了,且/data下的原有文件是不受影响的。

附录1、视频操作演示

000160. Linux系统环境中,动态扩容ext4文件系统分区 2025-07-07

本期博客地址 https://dasmz.com/?p=4655
本期视频地址 https://youtu.be/8rI6MIEVJqM

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

vi/vim的指令模式/命令模式

前缀、文档修改记录

20250609 初始化编辑此文章,完稿

章节1、需求描述

在 Vim 编辑器中,指令模式(又称命令模式)是你打开文件后默认进入的模式。在这个模式下,你不能直接输入文本,而是通过键盘输入命令来控制 Vim 的行为,比如移动光标、删除文字、复制粘贴等。

章节2、常见指令

vim的指令模式/命令模式
h	左移一个字符
l	右移一个字符
j	下移一行
k	上移一行
0	移动到行首
^	移动到行首第一个非空字符
$	移动到行尾
gg	移动到文件第一行
G	移动到文件最后一行
:n	跳转到第 n 行
:w	保存
:q	退出
:!	强制执行
/word	搜索word单词
:noh	取消高亮显示
:set nu	显示行号
:set nonu	关闭行号
:%s/old/new/g	替换文本内容,/g表格全局

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

Proxmox VE环境,运行一个原版openwrt的虚拟机

前缀、文档修改记录

20250522 初始化编辑此文章,完稿
20250803 更新文章,镜像版本24.10.2
20250804 更新Y2B视频讲解,PVE中创建1个Openwrt虚拟机,能通网络
20250805 更新文章,增加语言,源等配置 

章节1、需求描述

一个独立的PVE环境,最常见的all in one玩法,PVE中,是需要一个路由器系统的,优先选择openwrt作为路由器系统。

章节2、测试环境

PVE 8.1.4   // 这个不是最新版本的,不过没事
Openwrt 24.10.2 x86-64    // 这个是最新版本

章节3、 镜像文件

openwrt镜像文件下载,新版本的pve基本都是使用UEFI启动,优先下载使用 EFI 启动的openwrt镜像。 24.10.2 Tag-2025-8-3时间最新的版本

文件系统类型(ext4 vs squashfs)、是否支持 UEFI 启动,以及是否是 完整系统(combined) 或只是 根文件系统(rootfs)

https://downloads.openwrt.org/releases/24.10.2/targets/x86/64/openwrt-24.10.2-x86-64-generic-ext4-combined.img.gz

factory:用于硬件首次刷机
sysupgrade:用于升级现有 OpenWrt
combined.img(如 SquashFS):适合虚拟机或 USB 安装 

章节4、上传镜像

将gz格式的镜像解压缩为.img格式,然后,点PVE页面的上传按钮,进行文件上传

可以观察到文件在PVE中的位置 /var/lib/vz/template/iso/openwrt-24.10.2-x86-64-generic-ext4-combined.img

章节5、创建openwrt虚拟机

这里可以通过qm命令或者网页常规方式,创建一个无磁盘的虚拟机。

创建虚拟机 / 名称 OpenWRT

操作系统 / 不使用任何介质

系统 / 全部默认

磁盘 / 删掉默认,空白

核心 / KVM64 或者 host, +AES

内存 / 512MB ~ 2048MB

网卡 / virtio

章节6、 导入系统的img

qm importdisk $VMID /var/lib/vz/template/openwrt-*.img local-zfs

其中 $VMID,我这里是100,你们根据实际的填

执行命令为:
qm importdisk 102 /var/lib/vz/template/iso/openwrt-24.10.2-x86-64-generic-ext4-combined.img local-zfs

导入成功后,会出现“未使用的磁盘0”

双击未使用的磁盘,点击“添加”,并调整大小,增加10G的磁盘容量

并在 “选项”,”引导顺序” ,将刚刚增加的磁盘vm-100-disk-0拉到最上,让它“启用”,为第一优先级的引导

做完后,我一般直接把这台虚拟机转换为模板,这样方便后期的调试,按这个模板,创建各种测试用途的openwrt虚拟机。模板上右击,选择克隆,模式(完整),名称(自定义一个新名字)即可。

章节7、Openwrt地址段修改

修改文件 /etc/config/network ,我这里只有1个网卡,默认为LAN,如果需要WAN,可在控制台再增加一个网卡口,用于WAN的上联。

章节8、网页登录,修改网卡的配置参数

因为主路由开了DHCP SERVER,这个就关闭DHCP SERVER;

指定网关到当前网络的主路由IP

指定DNS到当前网络的主路由IP

(可选)我这里旁路由用,关闭IPv6

章节9、配置Openwrt的国内镜像源

网页登录Openwrt,系统System,软件Software,选择Configure opkg,修改 /etc/opkg/distfeeds.conf 中的内容

国内的源很多,一般清华,阿里,中科大……,这个你们随意选择。

//  原参数
src/gz openwrt_core https://downloads.openwrt.org/releases/24.10.2/targets/x86/64/packages
src/gz openwrt_base https://downloads.openwrt.org/releases/24.10.2/packages/x86_64/base
src/gz openwrt_kmods https://downloads.openwrt.org/releases/24.10.2/targets/x86/64/kmods/6.6.93-1-1745ebad77278f5cdc8330d17a3f43d6
src/gz openwrt_luci https://downloads.openwrt.org/releases/24.10.2/packages/x86_64/luci
src/gz openwrt_packages https://downloads.openwrt.org/releases/24.10.2/packages/x86_64/packages
src/gz openwrt_routing https://downloads.openwrt.org/releases/24.10.2/packages/x86_64/routing
src/gz openwrt_telephony https://downloads.openwrt.org/releases/24.10.2/packages/x86_64/telephony


// 更新参数,清华大学源
src/gz openwrt_core https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/24.10.2/targets/x86/64/packages
src/gz openwrt_base https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/24.10.2/packages/x86_64/base
src/gz openwrt_kmods https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/24.10.2/targets/x86/64/kmods/6.6.93-1-1745ebad77278f5cdc8330d17a3f43d6
src/gz openwrt_luci https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/24.10.2/packages/x86_64/luci
src/gz openwrt_packages https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/24.10.2/packages/x86_64/packages
src/gz openwrt_routing https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/24.10.2/packages/x86_64/routing
src/gz openwrt_telephony https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/24.10.2/packages/x86_64/telephony

配置完源,点击update lists,更新即可。

章节10、配置中文语言包

在输入框Filter 这里搜索 zh-cn

在luci-i18n-base-zh-cn 下载并安装,安装完成,刷新页面,应该就是中文了。

章节11、扩容/分区

系统默认的存储空间也就120MB总大小,我前面分配了16G的容量,没有充分用上,本章节讲解如何扩容/分区空间

原来各路径的容量信息:

下面参照官方的操作指引,更新扩容分区

https://openwrt.org/docs/guide-user/advanced/expand_root

如下都为命令行操作,先安装必要的软件

#注释 Install packages  安装必要的软件
root@OpenWrt:~# opkg update
root@OpenWrt:~# opkg install parted losetup resize2fs blkid unzip
 
#注释 Download expand-root.sh 下载官方的脚本代码,其中这个可选用电脑下载好后,手工上传到openwrt系统
root@OpenWrt:~# wget -U "" -O expand-root.sh "https://openwrt.org/_export/code/docs/guide-user/advanced/expand_root?codeblock=0"
 
#注释 运行脚本Source the script (自动生成 /etc/uci-defaults/70-rootpt-resize and /etc/uci-defaults/80-rootpt-resize, and adds them to /etc/sysupgrade.conf so they will be re-run after a sysupgrade)
root@OpenWrt:~# . ./expand-root.sh

#注释 执行分区扩容,并自动重启Resize root partition and filesystem (will resize partiton, reboot resize filesystem, and reboot again)
root@OpenWrt:~# sh /etc/uci-defaults/70-rootpt-resize
如果为M.2的NVMe的盘,因为实际为ext4文件系统,且没有必要全部容量扩进/分区,实际执行命令如下,增加16GB容量到/分区即可:
opkg update
opkg install parted losetup resize2fs blkid unzip lsblk losetup
parted -s /dev/nvme0n1 resizepart 2 16GB
losetup -a
losetup /dev/loop0 /dev/nvme0n1p2
resize2fs -f /dev/loop0
reboot

或者如果为2.5英寸的SSD盘
opkg update
opkg install parted losetup resize2fs blkid unzip lsblk losetup
parted -s /dev/sda resizepart 2 30GB
losetup -a
losetup /dev/loop0 /dev/sda2
resize2fs -f /dev/loop0
reboot

再次登录Openwrt,命令 df -h ,看到Available容量为~16GB,表示扩容完成。

章节12、安装软件 Passwall

必要的依赖软件

root@OpenWrt:~# opkg update
root@OpenWrt:~# opkg install coreutils 
root@OpenWrt:~# opkg install coreutils-base64
root@OpenWrt:~# opkg install coreutils-nohup
root@OpenWrt:~# opkg install curl
root@OpenWrt:~# opkg install ip-full
root@OpenWrt:~# opkg install libuci-lua
root@OpenWrt:~# opkg install lua
root@OpenWrt:~# opkg install luci-compat
root@OpenWrt:~# opkg install luci-lib-jsonc
root@OpenWrt:~# opkg install resolveip

去这里,搞一份文件,https://github.com/xiaorouji/openwrt-passwall/releases

本次2025-8-5下载的版本,25.8.5-1,根据各自的CPU架构&Openwrt版本,我这里要x86-64下载语言包和软件包

https://github.com/xiaorouji/openwrt-passwall/releases/download/25.8.5-1/luci-24.10_luci-app-passwall_25.8.5-r1_all.ipk

https://github.com/xiaorouji/openwrt-passwall/releases/download/25.8.5-1/luci-24.10_luci-i18n-passwall-zh-cn_25.216.51224.3ce0762_all.ipk

https://github.com/xiaorouji/openwrt-passwall/releases/download/25.8.5-1/passwall_packages_ipk_x86_64.zip

root@OpenWrt:~# opkg update
root@OpenWrt:~# opkg unzip
root@OpenWrt:~# unzip passwall_packages_ipk_x86_64.zip
// 依次安装如下
root@OpenWrt:# opkg install chinadns-ng_2025.06.20-r1_x86_64.ipk
root@OpenWrt:# opkg install dns2socks_2.1-r2_x86_64.ipk
root@OpenWrt:# opkg install geoview_0.1.10-r1_x86_64.ipk
root@OpenWrt:# opkg install hysteria_2.6.2-r1_x86_64.ipk 
root@OpenWrt:# opkg install ipt2socks_1.1.4-r3_x86_64.ipk
root@OpenWrt:# opkg install microsocks_1.0.5-r1_x86_64.ipk
root@OpenWrt:# opkg install naiveproxy_138.0.7204.35-r1_x86_64.ipk
root@OpenWrt:# opkg install shadow-tls_0.2.25-r1_x86_64.ipk
root@OpenWrt:# opkg install shadowsocks-rust-sslocal_1.23.5-r1_x86_64.ipk
root@OpenWrt:# opkg install shadowsocks-rust-ssserver_1.23.5-r1_x86_64.ipk  // 一般不需要安装
root@OpenWrt:# opkg install shadowsocksr-libev-ssr-local_2.5.6-r11_x86_64.ipk
root@OpenWrt:# opkg install shadowsocksr-libev-ssr-redir_2.5.6-r11_x86_64.ipk
root@OpenWrt:# opkg install shadowsocksr-libev-ssr-server_2.5.6-r11_x86_64.ipk  // 一般不需要安装
root@OpenWrt:# opkg install simple-obfs_0.0.5-r1_x86_64.ipk
root@OpenWrt:# opkg install sing-box_1.11.15-r1_x86_64.ipk
root@OpenWrt:# opkg install tcping_0.3-r1_x86_64.ipk
root@OpenWrt:# opkg install trojan-plus_10.0.3-r2_x86_64.ipk
root@OpenWrt:# opkg install tuic-client_1.0.0-r1_x86_64.ipk
root@OpenWrt:# opkg install v2ray-geoip_202507310022.1_all.ipk
root@OpenWrt:# opkg install v2ray-geosite_202507302215.1_all.ipk
root@OpenWrt:# opkg install v2ray-plugin_5.37.0-r1_x86_64.ipk
root@OpenWrt:# opkg install xray-core_25.7.26-r1_x86_64.ipk
root@OpenWrt:# opkg install xray-plugin_1.8.24-r1_x86_64.ipk
// 安装完各软件后,再安装这俩
root@OpenWrt:# opkg install luci-24.10_luci-app-passwall_25.8.1-r1_all.ipk
root@OpenWrt:# opkg install luci-24.10_luci-i18n-passwall-zh-cn_25.213.59897.f0cc846_all.ipk
2025-08-05 02:23:01: 系统未安装iptables或ipset或Dnsmasq没有开启ipset支持,无法使用iptables+ipset透明代理!
2025-08-05 02:23:01: 透明代理基础依赖 kmod-nft-socket 未安装...
2025-08-05 02:23:01: 透明代理基础依赖 kmod-nft-tproxy 未安装...
2025-08-05 02:23:01: 运行完成!

把缺的这俩在软件包里搜索安装,并重启一下即可。
删除 dnsmasq
安装 iptables-nft kmod-nft-socket kmod-nft-tproxy dnsmasq-full
并修改 passwall/高级设置/转发设置/防火墙/nftables

~ ~~~~~~~ 分割线 ~ ~~~~~~~

附录0、离线安装软件 fdisk

软件1、fdisk

//   terminfo_6.4-r2_x86_64.ipk
opkg install terminfo_*.ipk   
//   libncurses-dev_6.4-r2_x86_64.ipk  libncurses6_6.4-r2_x86_64.ipk  
opkg install libncurses6_*.ipk
//   fdisk_2.40.2-r1_x86_64.ipk
opkg install fdisk_*.ipk

软件2、resize2fs

//   resize2fs_1.47.0-r2_x86_64.ipk
opkg install resize2fs*.ipk

软件3、blkid

//   blkid_2.40.2-r1_x86_64.ipk      libblkid1_2.40.2-r1_x86_64.ipk
opkg install *blkid*.ipk

软件4、lsblk

//   libmount1_2.40.2-r1_x86_64.ipk lsblk_2.40.2-r1_x86_64.ipk
root@Router:~# opkg install libmount1_2.40.2-r1_x86_64.ipk
Installing libmount1 (2.40.2-r1) to root...
Configuring libmount1.
root@Router:~# opkg install lsblk_2.40.2-r1_x86_64.ipk
Installing lsblk (2.40.2-r1) to root...
Configuring lsblk.
root@Router:~# 

软件5、e2fs

root@Router:~# opkg install e2fsprogs_1.47.0-r2_x86_64.ipk 
Package e2fsprogs (1.47.0-r2) installed in root is up to date.
root@Router:~# 

附录1、视频操作演示

章节1-8,初始化1个openwrt虚拟机

000161. Proxmox VE环境,安装原版Openwrt系统 2025-08-04

本期博客地址 https://dasmz.com/?p=4625
本期视频地址 https://youtu.be/iqgECX1cGQw

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

Debian/Ubuntu系统,使用国内源安装docker-ce

前缀、文档修改记录

20250520 初始化编辑此文章,完稿

章节1、需求描述

国内服务器,懒得挂代理,想了想应该还是可以通过国内源来安装docker-ce的,本篇就实际来跑通一遍安装流程。

测试机的系统是 Debian 10 64位,国内服务器

章节2、操作步骤

2.1 卸载旧版本的docker-ce

此步骤需要慎重,先确认是否有运行的docker镜像,或者相关数据

apt remove docker docker-engine docker.io containerd runc

2.2 更新 APT 缓存

apt update
apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common

2.3 添加Docker的官方GPG密钥

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | apt-key add -

2.4 设置阿里云的 Docker 软件源

add-apt-repository \
   "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian \
   $(lsb_release -cs) \
   stable"

2.5 安装 Docker CE

apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io

本次测试环境安装到的版本 26.1.4-1~debian.10~buster Tag-20250520-2233

2.6 测试是否安装成功

root@debian:/# docker version
Client: Docker Engine - Community
 Version:           26.1.4
 API version:       1.45
 Go version:        go1.21.11
 Git commit:        5650f9b
 Built:             Wed Jun  5 11:29:15 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          26.1.4
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.21.11
  Git commit:       de5c9cf
  Built:            Wed Jun  5 11:29:15 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.33
  GitCommit:        d2d58213f83a351ca8f528a95fbd145f5654e957
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
root@debian:/# 

2.7 HelloWorld

配置镜像加速,因国家政策相关原因,国内已经收紧了docker镜像服务的提供,阿里云的镜像加速,也仅限其自身或者制品中心内的镜像,已经没啥用了。我研究了一下,要么自己部署私有镜像仓库,或者镜像加速,要么直接加速到docker.io官方地址,这个破世道。

https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

在这个页面,加速器地址这里,可以看到你私有的加速地址,恩,勿在公网公开。将下面registry.cn-hangzhou.aliyuncs.com 换成你私有的加速地址。

mkdir -p /etc/docker
cat << EOF | tee /etc/docker/daemon.json
{
  "registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"]
}
EOF

docker info | grep -i mirror     // 查看镜像是否生效,输出中包含配置的加速器地址,说明配置成功
阿里ACR变更内容
调整镜像加速器功能的使用范围:

仅限阿里云用户,在支持公网访问的阿里云产品上使用该镜像加速能力。

仅支持通过镜像加速器拉取限定范围内的容器镜像。
docker run hello-world

最终通过使用 tsocks 或 proxychains 转发流量,完成任务。

2.8 重启docker相关服务

systemctl daemon-reload
systemctl restart docker
systemctl enable docker     // 开机自动启动

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

Debian 12系统下,安装chrome浏览器,安装chrome driver

前缀、文档修改记录

20250509 初始化编辑此文章,完稿

章节1、需求描述

Debian 12系统下,安装chrome浏览器,配套安装chrome driver,以便用程序来驱动Chrome浏览器

章节2、操作步骤

2.1、安装必要的工具

root@server:~# apt update
root@server:~# apt install wget curl unzip

2.2、下载Chrome浏览器

root@server:~# mkdir -p /root/src

root@server:~# cd /root/src

root@server:~# wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
  // 从 Google 官方下载安装包

2.3、安装Chrome浏览器

使用 dpkg 安装,如果有依赖问题,再用 apt 修复即可

root@server:~#  cd /root/src/

root@server:~#  dpkg -i google-chrome-stable_current_amd64.deb
  // 本次安装到的版本是136.0.7103.92-1 Tag-2025-5-9

root@server:~#  apt --fix-broken install -y
  // 执行路径 /usr/bin/google-chrome

确认版本信息

root@server:~#  /usr/bin/google-chrome -version
Google Chrome 136.0.7103.92  

// Tag-2025-5-9 输出版本号,说明安装成功

2.4、下载和安装 ChromeDriver

ChromeDriver 版本需要和 Chrome 浏览器版本对应,所以,刚刚安装的Chrome版本务必记录下来。

低于115的版本的官方地址 https://chromedriver.chromium.org/downloads

https://developer.chrome.com/docs/chromedriver/downloads

图/官方提示:

高于115或者更新版本的官方地址 https://googlechromelabs.github.io/chrome-for-testing/

下载其中chromedriver的linux64版本即可,https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.92/linux64/chromedriver-linux64.zip

root@server:~#  cd /root/src/

root@server:~#  wget https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.92/linux64/chromedriver-linux64.zip
  // 版本编号要跟Chrome浏览器的一致


root@server:~# unzip chromedriver-linux64.zip
Archive:  chromedriver-linux64.zip
  inflating: chromedriver-linux64/LICENSE.chromedriver  
  inflating: chromedriver-linux64/THIRD_PARTY_NOTICES.chromedriver  
  inflating: chromedriver-linux64/chromedriver  
root@server:~#  

root@server:~# mv chromedriver-linux64/chromedriver /usr/bin/chromedriver
root@server:~# chmod +x /usr/bin/chromedriver
  // 挪目录,赋权限

root@server:~# chromedriver --version
  // 确认版本号,显示就是正常的,务必跟Chrome版本一致

章节3、测试代码

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# by Dasmz
# 2025-5-9
# 
import time
import random
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

CHROMEDRIVER_PATH = '/usr/bin/chromedriver'
SCREENSHOT_PATH = '/var/www/html/ScreenShot.png'

URL_LIST = ['URL1','URL2','URL3','URL4','URL5'...]

def getNow():
    now = datetime.now()
    return now.strftime("%Y-%m-%d %H:%M:%S")
    
def create_driver(user_agent):
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')  # 无界面模式
    chrome_options.add_argument("--window-size=1920x1080")  # 窗口大小
    chrome_options.add_argument('--disable-gpu')   # 关闭GPU加速
    chrome_options.add_argument("--mute-audio")   # 关闭声音
    chrome_options.add_argument("--no-sandbox")   # 无沙箱
    chrome_options.add_argument("--disable-dev-shm-usage")  # 不使用/dev/shm共享内存目录
    chrome_options.add_argument("--disable-extensions")   # 关闭扩展程序
    chrome_options.add_argument("--log-level=3")   # 只显示致命错误FATAL
    chrome_options.add_argument('--disable-application-cache')   # 关闭 Chrome 的应用缓存,包括页面缓存、离线缓存
    chrome_options.add_argument('--incognito')   # 隐身模式,每次打开网页都是新会话,不会用缓存、也不会保存 cookie
    chrome_options.add_argument('--disk-cache-size=0')   # 磁盘缓存设为 0 字节
    chrome_options.add_argument(f"--user-agent={user_agent}")
    
    # 禁止图片加载
    # prefs = {"profile.managed_default_content_settings.images": 2}
    # chrome_options.add_experimental_option("prefs", prefs)
    
    driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, options=chrome_options)
    driver.set_window_size(1920, 1080)   # 设置分辨率 (宽, 高)
    return driver

def run_chrome(driver, url):
    try:
        driver.get(url)
        # 等待 body 元素加载完成
        time.sleep(1.5)  # 给浏览器的网页加载的时间
        WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'body')))
        
        print(f"标题: {driver.title}")
        print(f"URL: {driver.current_url}")
        # print(f"页面源码长度: {len(driver.page_source)}")
        
        # 网页加载情况截图
        driver.save_screenshot(SCREENSHOT_PATH)
    except Exception as e:
        print(f"出错: {e}")

def go2web(driver):
    try:
        target_url = random.choice(URL_LIST)
        run_chrome(driver, target_url)
    except Exception as e:
        print(f"访问出错: {e}")

if __name__ == '__main__':
    user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36'
    
    driver = create_driver(user_agent)
    
    try:
        for i in range(1, 40000000):
            print(f"\n\n第 {i} 次访问 {getNow()}")
            go2web(driver)
            # time.sleep(1)  # 可调整等待时间
    except KeyboardInterrupt:
        print("手动中断")
    finally:
        driver.quit()

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨