Python自动化(3)——鼠标模拟

Python自动化(3)——鼠标模拟

前台鼠标模拟

鼠标模拟和键盘模拟类似,也是分前台和后台模拟。话不多说直接,上代码:

import time
import win32api
import win32con
import win32gui
from ctypes import *MOUSEEVENTF_LEFTDOWN = 0x2
MOUSEEVENTF_LEFTUP = 0x4
MOUSEEVENTF_MIDDLEDOWN = 0x20
MOUSEEVENTF_MIDDLEUP = 0x40 
MOUSEEVENTF_RIGHTDOWN = 0x8
MOUSEEVENTF_RIGHTUP = 0x10 
MOUSEEVENTF_MOVE = 0x1class FrontstageMouse():def __init__(self):print('FrontstageMouse init')def bind(self, hwnd):self.hwnd = hwnddef getRelativePosition(self, x, y):left, top, right, bottom = win32gui.GetWindowRect(self.hwnd)return [left + x, top + y]# 前台模拟方法1——使用win32api.mouse_event(默认)  ############################################# 模拟鼠标的按键按下def clickDown(self, x, y, button="l"):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button = button.lower()if button == "l":win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)elif button == "m":win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEDOWN,0,0,0,0)elif button == "r":win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN,0,0,0,0)print('clickDown x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的按键抬起def clickUp(self, x, y, button="l"):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button = button.lower()if button == "l":win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)elif button == "m":win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEUP,0,0,0,0)elif button == "r":win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP,0,0,0,0)print('clickUp x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的点击def click(self, x, y, button="l", interval=0.1):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button = button.lower()if button == "l":win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)time.sleep(interval)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)elif button == "m":win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEDOWN,0,0,0,0)time.sleep(interval)win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEUP,0,0,0,0)elif button == "r":win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN,0,0,0,0)time.sleep(interval)win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP,0,0,0,0)print('clicked x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的左键双击def doubleClick(self, x, y):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)time.sleep(0.05)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)print('doubleClick x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的左键拖动(即在第一个点按下,拖动至第二个点抬起# 但是,不知道为啥,实际上是不准的,滑动的值会比实际的多2倍左右,因此默认除以2# 有时候会误触导致滑动改成点击def slide(self, x1, y1, x2, y2):# win32api.SetCursorPos(self.getRelativePosition(int(x1), int(y1)))time.sleep(0.1)offsetX = int(x2)/2 - int(x1)/2offsetY = int(y2)/2 - int(y1)/2print("offsetX: " + str(offsetX))print("offsetY: " + str(offsetY))win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)time.sleep(0.1)win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(offsetX), int(offsetY))time.sleep(0.1)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)print('slide x1: ' + str(x1) + ', y1: ' + str(y1) + ', x2: ' + str(x2) + ', y2: ' + str(y2))# 前台模拟方法2——使用ctypes  ############################################# 模拟鼠标的按键按下def clickDown_2(self, x, y, button="l"):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button = button.lower()if button == "l":windll.user32.mouse_event(MOUSEEVENTF_LEFTDOWN)elif button == "m":windll.user32.mouse_event(MOUSEEVENTF_MIDDLEDOWN)elif button == "r":windll.user32.mouse_event(MOUSEEVENTF_RIGHTDOWN)print('clickDown_2 x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的按键抬起def clickUp_2(self, x, y, button="l"):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button = button.lower()if button == "l":windll.user32.mouse_event(MOUSEEVENTF_LEFTUP)elif button == "m":windll.user32.mouse_event(MOUSEEVENTF_MIDDLEUP)elif button == "r":windll.user32.mouse_event(MOUSEEVENTF_RIGHTUP)print('clickUp_2 x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标左键单击def click_2(self, x, y, button='l', interval=0.05):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button = button.lower()if button == "l":windll.user32.mouse_event(MOUSEEVENTF_LEFTDOWN)time.sleep(interval)windll.user32.mouse_event(MOUSEEVENTF_LEFTUP)elif button == "m":windll.user32.mouse_event(MOUSEEVENTF_MIDDLEDOWN)time.sleep(interval)windll.user32.mouse_event(MOUSEEVENTF_MIDDLEUP)elif button == "r":windll.user32.mouse_event(MOUSEEVENTF_RIGHTDOWN)time.sleep(interval)windll.user32.mouse_event(MOUSEEVENTF_RIGHTUP)print('clicked_2 x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的左键双击def doubleClick_2(self, x, y):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))windll.user32.mouse_event(MOUSEEVENTF_LEFTDOWN)time.sleep(0.05)windll.user32.mouse_event(MOUSEEVENTF_LEFTUP)time.sleep(0.05)windll.user32.mouse_event(MOUSEEVENTF_LEFTDOWN)time.sleep(0.05)windll.user32.mouse_event(MOUSEEVENTF_LEFTUP)print('doubleClick_2 x: ' + str(x) + ', y: ' + str(y))def slide_2(self, x1, y1, x2, y2):# win32api.SetCursorPos(self.getRelativePosition(int(x1), int(y1)))time.sleep(0.1)offsetX = int(x2)/2 - int(x1)/2offsetY = int(y2)/2 - int(y1)/2print("offsetX: " + str(offsetX))print("offsetY: " + str(offsetY))win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)time.sleep(0.1)win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(offsetX), int(offsetY))time.sleep(0.1)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)print('slide x1: ' + str(x1) + ', y1: ' + str(y1) + ', x2: ' + str(x2) + ', y2: ' + str(y2))

这里使用了两个不同的库分别实现,分别是win32api和ctypes库。win32库实际上也是实现鼠标后台模拟的关键,也可以实现前台模拟,使用mouse_event方法。
其中,win32api中mouse_event的函数原型:
VOID mouse_event(DWORD dwFlags,DWORD dx,DWORD dwFlags,OWORD dx,DWORD dy, DWORD dwData, DWORD dwExtralnfo);
dwFlags:标志位集,指定点击按钮和鼠标动作的多种情况。此参数里的各位可以是下列值的任何合理组合:
MOOSE_EVENTF_ABSOLOTE:表明参数dX,dy含有规范化的绝对坐标。如果不设置此位,参数含有相对数据:相对于上次位置的改动位置。此标志可被设置,也可不设置,不管鼠标的类型或与系统相连的类似于鼠标的设备的类型如何。要得到关于相对鼠标动作的信息,参见下面备注部分。
MOOSEEVENTFMOVE:表明发生移动。
M00SEEVENTF_LEFTDOWN:表明接按下鼠标左键。
M00SEEVENTF_LEFTUP:表明松开鼠标左键。
MOOSEEVENTF_RIGHTDOWN:表明按下鼠标右键。
MOOSEEVENTF_RIGHTUP:表明松开鼠标右键。
MOOSEEVENTF_MIDDLEDOWN:表明按下鼠标中键。
MOOSEEVENTF_MIDDLEUP:表明松开鼠标中键。
MOOSEEVENTF_WHEEL:在Windows NT中如果鼠标有一个轮,表明鼠标轮被移动。移动的数量由dwData给出。
dx:指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOOSEEVENTF_ABSOLOTE的设置。给出的绝对数据作为鼠标的实际X坐标;给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量,表明鼠标已经移动。
dy:指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOOSEEVENTF_ABSOLVTE的设置。给出的绝对数据作为鼠标的实际y坐标,给出的相对数据作为移动的mickeys数。
dwData:如果dwFlags为MOOSEEVENTF_WHEEL,则dwData指定鼠标轮移动的数量。正值表明鼠标轮向前转动,即远离用户的方向;负值表明鼠标轮向后转动,即朝向用户。一个轮击定义为WHEEL_DELTA,即120。
如果dwFlagsS不是MOOSEEVENTF_WHEEL,则dWData应为零。
dwExtralnfo:指定与鼠标事件相关的附加32位值。应用程序调用函数GetMessgeExtrajnfo来获得此附加信息。
返回值:无。

后台鼠标模拟

import time
import win32api
import win32con
import win32com
import win32gui
import pythoncom
import mathclass BackstageMouse():def __init__(self):print('BackstageMouse init')def bind(self, hwnd):self.hwnd = hwnd# 聚焦句柄对应的窗口def focusHwnd(self):pythoncom.CoInitialize()shell = win32com.client.Dispatch("WScript.Shell")shell.SendKeys('%')win32gui.SetForegroundWindow(self.hwnd)# 后台模拟方法1——使用SendMessage(默认)  ############################################# 模拟鼠标的移动def move(self, x, y):point = win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, win32con.MK_LBUTTON, point)# 模拟鼠标的按键按下def clickDown(self, x, y, button="l"):point = win32api.MAKELONG(int(x), int(y))button = button.lower()if button == "l":win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, point)elif button == "m":win32api.SendMessage(self.hwnd, win32con.WM_MBUTTONDOWN, win32con.MK_MBUTTON, point)elif button == "r":win32api.SendMessage(self.hwnd, win32con.WM_RBUTTONDOWN, win32con.MK_RBUTTON, point)print('clickDown x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的按键抬起def clickUp(self, x, y, button="l"):point = win32api.MAKELONG(int(x), int(y))button = button.lower()if button == "l":win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)elif button == "m":win32api.SendMessage(self.hwnd, win32con.WM_MBUTTONUP, win32con.MK_MBUTTON, point)elif button == "r":win32api.SendMessage(self.hwnd, win32con.WM_RBUTTONUP, win32con.MK_RBUTTON, point)print('clickUp x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的点击def click(self, x, y, button="l", interval=0.1):point = win32api.MAKELONG(int(x), int(y))button = button.lower()if button == "l":win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, point)time.sleep(interval)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)elif button == "m":win32api.SendMessage(self.hwnd, win32con.WM_MBUTTONDOWN, win32con.MK_MBUTTON, point)time.sleep(interval)win32api.SendMessage(self.hwnd, win32con.WM_MBUTTONUP, win32con.MK_MBUTTON, point)elif button == "r":win32api.SendMessage(self.hwnd, win32con.WM_RBUTTONDOWN, win32con.MK_RBUTTON, point)time.sleep(interval)win32api.SendMessage(self.hwnd, win32con.WM_RBUTTONUP, win32con.MK_RBUTTON, point)print('clicked x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的左键双击def doubleClick(self, x, y):point = win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDBLCLK, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)print('doubleClick x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标移动到坐标,并进行左键单击def moveToPosClick(self, x, y):point = win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)print('moveToPosClick x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标移动到坐标,并进行左键双击def moveToPosDoubleClick(self, x, y):point = win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDBLCLK, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)print('moveToPosDoubleClick x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标使用滚轮向上滚动# 需要聚焦到窗口def wheelUp(self, x, y):self.focusHwnd()point = win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEWHEEL, win32con.WHEEL_DELTA * 5, point)print('wheelDown x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标使用滚轮向下滚动# 需要聚焦到窗口def wheelDown(self, x, y):self.focusHwnd()point = win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEWHEEL, win32con.MK_LBUTTON, point)print('wheelDown x: ' + str(x) + ', y: ' + str(y))# 模拟鼠标的左键拖动(即在第一个点按下,拖动至第二个点抬起)# @step 步长,模拟拖动会将一个操作分开多次来模拟,次数=拖动的长度/步长# @delay 拖动时间,默认0.5秒# @isNeedBtnUp 是否需要弹起鼠标,默认是,若不弹起可通过多次调用实现轨迹拖动def slide(self, x1, y1, x2, y2, isNeedBtnUp=True, step=20, delay=0.5):offsetX = x2-x1offsetY = y2-y1count = int(math.sqrt(offsetX*offsetX + offsetY*offsetY) / step)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, win32api.MAKELONG(int(x1), int(y1)))for i in range(count):point2 = win32api.MAKELONG(int(x1+offsetX/count*(i+1)), int(y1+offsetY/count*(i+1)))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, win32con.MK_LBUTTON, point2)time.sleep(delay/count)if isNeedBtnUp:win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, 0, point2)print('slide x1: ' + str(x1) + ', y1: ' + str(y1) + ', x2: ' + str(x2) + ', y2: ' + str(y2))

这里同样使用win32api的SendMessage方法来实现鼠标的后台模拟,此方法的原型在键盘模拟中提过了,这里不再复述。

使用后台键盘模拟,需要绑定窗口句柄,关于窗口句柄的获取,可以看看下面这篇文章:Python自动化(1)——获取窗口句柄

完整自动化工程代码:https://gitee.com/chj-self/PythonRobotization

大佬们找到问题欢迎拍砖~

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

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

相关文章

java基于ssm+jsp 高校四六级报名管理系统

1前台首页功能模块 高校四六级报名管理系统,在系统首页可以查看首页、四六级报名、新闻资讯、我的、跳转到后台、在线客服等内容,如图1所示。 图1系统功能界面图 学生登录、学生注册,在注册页面可以填写学号、密码、姓名、学院、班级、手机、…

决策树算法详细介绍原理和实现

决策树是一种常用的分类算法,它通过一系列的问题将数据分割成不同的分支,最终确定数据属于哪个类别。下面是决策树的原理、实现方式以及一个案例实现的详细介绍。 决策树原理 特征选择:决策树的构建过程首先需要选择一个特征作为节点&#…

hostname: Name or service not known

rootuser-PC:~# hostname -i hostname: Name or service not known rootuser-PC:~# vi /etc/hosts 10.170.200.148 node148 ## 设置hostname rootuser-PC:~# hostnamectl --static set-hostname node148 ## 再执行的hostname的时候就不会报错了. rootuser-PC:~# hostname…

yolov8中配置文件args.yaml解读

task: 指定任务类型,这里是 detect,表示进行目标检测任务。mode: 指定模式,train 表示训练模式。model: 模型权重文件的路径,这里是预训练模型权重的路径。data: 数据集配置文件的路径,指定了训练和验证数据的位置和格…

现货黄金应用价格行为交易所需要的环境

在现货黄金投资中,投资者常用价格行为交易法来分析走势。简单来说,这种方法就是只看K线和支撑阻力位,顶多加一些简单的指标,以此构建分析和交易的系统。由于价格行为简单易学,现在的投资者或多或少都在使用这个方法。但…

短视频批量下载工具源码逻辑解析(软件)

短视频批量提取第三篇关于视频提取下载的思路 一:概述 因为上一篇不完整,这里其实就是补充第二篇关于源码思路。这里不针对视频评论的提取,只对视频分享链接批量导入下载进行思路解析 二:难点 通常情况下如果直接访问详情页进行…

【稀疏三维重建】Flash3D:单张图像重建场景的GaussianSplitting

项目主页:https://www.robots.ox.ac.uk/~vgg/research/flash3d/ 来源:牛津、澳大利亚国立 提示: 文章目录 摘要1.引言2.相关工作3.方法3.1 背景:从单个图像中重建场景3.2 单目 4.实验4.14.2 跨域新视角合成4.3 域内新视图合成4.4…

学懂C#编程:常用高级技术——委托(Delegate)应用场景——秒懂 多播委托

多播委托:一个委托可以引用多个方法,形成多播委托,调用时所有方法都会执行。 在C#中,委托支持多播,这意味着一个委托实例可以绑定多个方法。当这样的委托被调用时,所有绑定的方法会按照它们添加到委托的顺序…

24h业务系统不间断,HA双活存储能做到

封面 Infortrend GS统一存储支持HA双活功能。之前GS的高可用性是通过双冗余控制器设计来实现的。现在企业用两台GS设备的HA双活功能,进一步增强高可用性。HA双活功能在两台GS存储系统上保存相同的数据副本,保证数据不会丢失。在一台GS故障时另一台继续…

【Python高级编程】pickle`文件处理:序列化与反序列化

使用pickle模块可以在Python中方便地序列化和反序列化Python对象。以下是一个例子,展示了如何处理pickle文件,包括如何保存数据到pickle文件和从pickle文件加载数据。假设我们有一些数据需要保存并在之后加载。 示例代码 保存数据到 pickle 文件 impo…

vb.net c#一键编绎引用DLL如何做?编绎成独立EXE

.net c#一键编绎引用如何做? 3个工程有依懒关系 ClassLibrary1,ClassLibrary2,MainProject (主工程) ClassLibrary2依赖ClassLibrary1,MainProject依赖前2个 如何实现一键按顺序编绎,自动添加前…

【OpenGauss源码学习 —— (ALTER TABLE(SET attribute_option))】

ALTER TABLE(SET attribute_option) ATExecSetOptions 函数 声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。…

CesiumJS整合ThreeJS插件封装

最近做项目有一个三维需求使用CesiumJS比较难以实现,发现THREEJS中效果比较合适,于是准备将THREEJS整合到CesiumJS中 为实现效果所需我们找到官方Integrating Cesium with Three.js博客,于是根据该博客提供的思路去实现整合 文章目录 一、创…

Java Array示例说明

Java Array示例说明 数组是相同类型的元素的集合。例如,int数组包含整数元素,String数组包含String元素。Array的元素存储在内存中的相邻位置。Java中的数组基于零基索引系统,这意味着第一个元素位于索引0处。 数组如下所示: i…

《计算机英语》缩略词补充

Unit1 FTP(File Transfer Protocol) 文件传输协议 LCD(Liquid Crystal Display) 液晶显示器 GUI(Graphical User Interface) 图形用户界面 VCD(Video Compact Disc)视频光盘 CAD&…

接口异步回调

接口异步回调 有些接口,内部逻辑非常复杂,非常耗时。 可以通过接口异步回调来实现,避免超时。 比如 , 系统A 的 A1接口调用 系统B 的 B1接口, 系统B在完成功能后,系统B 回调系统A 的 另一个接口 A2。 小…

LabVIEW与数字孪生

LabVIEW与数字孪生技术在工业自动化、智慧城市、医疗设备和航空航天等领域应用广泛,具备实时数据监控、虚拟仿真和优化决策等特点。开发过程中需注意数据准确性、系统集成和网络安全问题,以确保数字孪生模型的可靠性和有效性。 经典应用:LabV…

今天在地铁认识一个女程序员,在外包公司工作三年,只赔偿4000

“下一站,xx软件园……” 地铁广播响起,车厢里再次骚动起来。提着电脑包的、抱着文件袋的,一个个行色匆匆,奔赴各自的“战场”。 在这熙熙攘攘的人群中,我注意到了一位特别的女生。她看起来很年轻,却难掩眉…

MySQL学习笔记——函数和约束

函数和约束 函数字符串函数数值函数日期函数流程函数 约束分类外键约束删除/更新行为 学习黑马MySQL课程记录笔记,用于复习。 函数 字符串函数 MySQL中常用的字符串函数: 函数功能concat(S1,S2,…Sn)字符串拼接,将S1,S2&#x…

ru俄罗斯域名如何申请SSL证书?

我们日常看到的都是com这种国际域名比较普遍,尤其是主流网站,主要原因考虑的其通用性,那么对于地方性的域名大家很少看到,比如俄罗斯国家域名.ru大家还是有些陌生的,但要说中国.CN域名那你就很熟悉了。 有用户在申请过…