python模块详解 | selenium(持续更新中)
目录:
关于selenium
selenium方法详解
- Selenium
Selenium是⼀个⽤于测试⽹站的⾃动化测试⼯具,⽀持各种浏览器包括Chrome、Firefox、Safari等主流界⾯浏览器,同时也⽀持phantomJS⽆界⾯浏览器。另外,selenium用来爬虫也是杠杠的,可以应对大多数的反爬,为什么说是大多数呢?呵呵,懂的,都懂。
- 安装Selenium
pip install Selenium
- 安装浏览器驱动
Selenium3.x调⽤浏览器必须有⼀个webdriver驱动⽂件
驱动下载 selenium各浏览器驱动下载地址
- 配置环境变量
将下载的exe驱动文件,移动到python安装目录下的Scripts文件夹下
更多配置方法 参考浏览器驱动环境配置
⼊门参考⽂献 Selenium⼊门
定位元素
- 8种常规定位方法:id,name,class_name,tag_name,link_text,partial_link_text,xpath,css_selector
- 参考官网 selenium元素定位
定位⼀个元素 | 定位多个元素(返回一个列表) | 含义 |
find_element_by_id | find_elements_by_id | id |
find_element_by_name | find_elements_by_name | name |
find_element_by_xpath | find_elements_by_xpath | xpath表达式 |
find_element_by_link_text | find_elements_by_link_text | 完整超链接文本 |
find_element_by_partial_link_text | find_elements_by_partial_link_text | 部分超链接文本 |
find_element_by_tag_name | find_elements_by_tag_name | 标签名 |
find_element_by_class_name | find_elements_by_class_name | 类名 |
find_elements_by_css_selector | find_elements_by_css_selector | css选择器 |
ps:除了上面的公共方法,也有两个在页面对象定位器的私有方法: find_element、find_elements
- xpath定位的N种写法
- dr.find_element_by_xpath("//*[@id='kw']")
- dr.find_element_by_xpath("//*[@name='wd']")
- dr.find_element_by_xpath("//input[@class='s_ipt']")
- dr.find_element_by_xpath("/html/body/form/span/input")
- dr.find_element_by_xpath("//span[@class='soutu-btn']/input")
- dr.find_element_by_xpath("//form[@id='form']/span/input")
- dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")
- css定位的N种写法
- dr.find_element_by_css_selector("#kw")
- dr.find_element_by_css_selector("[name=wd]")
- dr.find_element_by_css_selector(".s_ipt")
- dr.find_element_by_css_selector("html > body > form > span > input")
- dr.find_element_by_css_selector("span.soutu-btn> input#kw")
- dr.find_element_by_css_selector("form#form > span > input")
- link_text定位的写法(实例)
假如⻚⾯上有⼀组⽂本链接(link_text)
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>
<a class="mnav" href="http://www.hao123.com" name="tj_trhao123">hao123</a>
通过link_text定位:
- dr.find_element_by_link_text("新闻")
- dr.find_element_by_link_text("hao123")
通过partial_link_text定位:
- dr.find_element_by_partial_link_text("新")
- dr.find_element_by_partial_link_text("hao")
- dr.find_element_by_partial_link_text("123")
元素操作
- clear # 清除元素的内容
- send_keys # 模拟按键输入
- click # 点击元素
- submit # 提交表单
- size # 获取元素的尺寸,返回一个字典:{'x': 000, 'y': 000}
- text # 获取元素的文本
- get_attribute(name) # 获取属性值
- location # 获取元素坐标,先找到要获取的元素,再调用该方法,返回一个字典:{'height': 000, 'width': 000}
- is_displayed() # 设置该元素是否可见
- is_enabled() # 判断元素是否被使用
- is_selected() # 判断元素是否被选中
- tag_name # 返回元素的tagName
ps:如果需要输入中文,防止编码错误使用send_keys(u"中文用户名")。
浏览器操作
- title # 返回页面标题
- page_source # 返回页面源码
- current_url # 获取当前页面的URL
- refresh # 刷新浏览器
- set_window_size() # 设置浏览器的大小
- set_window_position() # 设置浏览器的坐标
- set_window_rect() # 设置浏览器的矢量
- maximize_window() # 最大化窗口
- minimize_window() # 最小化窗口
- close() # 关闭页面
- quit() # 关闭窗口
鼠标事件
- ActonChains(driver) # 构造ActionChains对象
- click(on_element) # 左击
- context_click(on_element) # 右键,另存为等行为
- double_click(on_element) # 左键双击,地图web可实现放大功能
- drag_and_drop(source,target) # 左键拖动,源元素按下左键移动至目标元素释放
- drag_and_drop_by_offset(source, xoffset, yoffset) # 拖拽到某个坐标然后松开
- key_down(value, element=None) # 按下某个键盘上的键
- key_up(value, element=None) # 松开某个键
- move_by_offset(xoffset, yoffset) # 鼠标从当前位置移动到某个坐标
- move_to_element(on_element) # 鼠标悬停
- move_to_element_with_offset(to_element, xoffset, yoffset) # 移动到距某个元素(左上角坐标)多少距离的位置
- click_and_hold(on_element) #左键点击不松开
- perform() # 在通过调用该函数执行ActionChains中存储行为
- 例:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains#引⼊ ActionChains 类
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")
element= driver.find_element_by_link_text("设置")#定位元素
ActionChains(driver).move_to_element(element).perform()#3.对定位到的元素执⾏⿏标悬停操作
键盘事件
参考:http://selenium-python.readthedocs.org/api.html
提供键盘按键操作的类:webdriver.common.keys
from selenium.webdriver.common.keys import Keys
send_keys(Keys.ENTER) # 按下回车键
send_keys(Keys.TAB) # 按下Tab制表键
send_keys(Keys.SPACE) # 按下空格键space
send_keys(Kyes.ESCAPE) # 按下回退键Esc
send_keys(Keys.BACK_SPACE) # 按下删除键BackSpace
send_keys(Keys.SHIFT) # 按下shift键
send_keys(Keys.CONTROL) # 按下Ctrl键
send_keys(Keys.ARROW_DOWN) # 按下鼠标光标向下按键
send_keys(Keys.CONTROL,'a') # 组合键全选Ctrl+A
send_keys(Keys.CONTROL,'c') # 组合键复制Ctrl+C
send_keys(Keys.CONTROL,'x') # 组合键剪切Ctrl+X
- send_keys(Keys.F1…Fn) # 键盘 F1…Fn
设置元素等待
- 强制等待
- 隐式等待
- 显式等待
参考链接:http://www.testclass.net/selenium_python/element-wait/
多表单切换
在Web应⽤中经常会遇到frame/iframe表单嵌套⻚⾯的应⽤,WebDriver只能在⼀个⻚⾯上对元素识别与定位,对于frame/iframe表单内嵌⻚⾯上的元素⽆法直接定位。这时就需要通过switch_to.frame()⽅法将当前定位的主体切换为frame/iframe表单的内嵌⻚⾯中。
- switch_to.frame()
将当前定位的主体切换为frame/iframe表单的内嵌⻚⾯,默认可以直接取表单的 id 或name属性。如果iframe没有可⽤的id和name属性,则可以通过查找iframe标签,进⾏定位。
- switch_to.default_content()
跳回最外层的⻚⾯
- 例
#先通过 xpth 定位到 iframe
xf = driver.find_element_by_xpath('//*[@class="if"]')
#再将定位对象传给 switch_to_frame()方法
driver.switch_to_frame(xf)
……
driver.switch_to_default_content()
多窗⼝切换
在⻚⾯操作过程中有时候点击某个链接会弹出新的窗⼝,这时就需要主机切换到新打开的窗⼝上进⾏操作。WebDriver提供了switch_to.window()⽅法,可以实现在不同的窗⼝之间切换。
- current_window_handle #获得当前窗⼝句柄
- window_handles #返回所有窗⼝的句柄到当前会话
- switch_to.window() #⽤于切换到相应的窗⼝,与上⼀节的switch_to.frame()类似,前者⽤于不同窗⼝的切换,后者⽤于不同表单之间的切换
- 例:
c_win = driver.current_driver.current_windle_handle
driver.switch_to_window(c_win)
对话框操作
在WebDriver中处理JavaScript所⽣成的alert、confirm以及prompt⼗分简单,具体做法是使⽤ switch_to.alert 或switch_to_alert ()⽅法定位到 alert/confirm/prompt,然后使⽤text/accept/dismiss/send_keys 等⽅法进⾏操作。
- switch_to_alert() # 切入到警告框
- switch_to.alert() # 切入到警告框
- text # 返回 alert/confirm/prompt 中的⽂字信息
- accept() # 接受现有警告框
- dismiss() # 解散现有警告框
- send_keys(keysToSend) # 发送⽂本⾄警告框。keysToSend:将⽂本发送⾄警告框。
- 例:
al = driver.switch_to_alert()
al.accept()
al.text
复选框操作
- is_selected() #返回布尔值,判断是否被选中
1、单选框(radio)
2、复选框(checkbox)
3、下拉框(select)
导⼊选择下拉框Select类,使⽤该类处理下拉框操作:
from selenium.webdriver.support.select import Select
- 选择下拉框选项的⽅法
- select_by_value(“选择值”) # 相当于我们使⽤⿏标选择下拉框的值
- select_by_index(索引值) # 以传入的index值来查找匹配的元素并选择对应选项(索引从0开始计数)
- select_by_visible_text(“文本”) # 选择所有文本显示的option元素,
- 返回options信息的方法
- options # 返回所有的选项的列表,其中选项都是WebElement元素
- all_selecetd_options # 返回所有被选中的选项的列表,其中选线均为WebElement元素,输出所有被选中的选项,适合于能多选的下拉框
- first_selected_option # 返回第一个被选中的选项
- 取消下拉框选择的方法
- deselect_by_index() #以传入的索引值来查找匹配的元素并取消选择
- deselect_by_value() #以传入的value属性值来查找匹配的元素并取消选择
- deselect_by_visible_text() #以传入的文本内容来查找匹配的元素并取消选择
- deselect_all() #将所有的选项清除
ps:上述四种方法仅用于多选下拉框,即设置了multiple=“multiple”属性的select标签,这种下拉框可以多选。
文件上传
selenium没有提供直接的文件上传功能,目前主要有以下几种解决方案:
- seng_keys()
- AutoIT
- python pywin32 模块
1、send_keys()
对于通过input标签实现的上传功能,可以将其看作是⼀个输⼊框,定位到用于上传的input标签,接着通过send_keys()指定本地⽂件路径的⽅式,实现⽂件上传。
例:
from selenium import webdriver
import os
driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)
# 定位上传按钮,添加本地⽂件
driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
driver.quit()
2、AutoIT
AutoIT通过操作Windows窗口控件来实现自动化任务。selenium通过AutoIT来操作Windows窗口,实质是通过python代码来调用AutoIT生成的脚本.exe文件,即利用AutoIT编写适合的脚本,然后将脚本编译成可执行文件,在自动化测试实现时,直接调用此脚本实现文件上传。
ps:编写脚本和编译需要借助AutoIT提供的工具,但是脚本编译成可执行文件后,可直接使用,不需要安装AutiIT。
- AutoIT下载:https://www.autoitscript.com/site/
- AutoIT的使用:
- 探测控件(AutoIt Window Info工具)
- 编写脚本(Autoit Window Info编辑器)
- 验证脚本(Autoit Window Info Tool go)
- 编译成可执行文件(Compile Script to.exe)
- 调用可执行文件
- 参数化(在python程序中向可执行文件传入参数)
- 多个参数化(实现多文件上传)
3、pywin32
pywin32式用于访问Windows系统API的python模块,最核心的方法是:
- win32api #用python对win32的本地API库进行封装
- win32con #win32的常量定义
- win32gui #
文件下载
文件下载(另存为),跟文件上传类似,可以使用AutoIt、win32api解决
1、win32api
- 例:下载搜狗图片
import win32api,win32con
driver.get(sg_url)
ActionChains(driver).move_to_element(driver.find_element_by_link_text('图片')).click().perform()#点击跳转到图片
time.sleep(1)
ActionChains(driver).move_to_element(driver.find_element_by_xpath('//*[@id="feed_list"]/div[1]/ul/li[1]/a/img')).context_click().perform()
win32api.keybd_event(40,0,0,0)#40对应的是向下键,由于’另存为‘在菜单的顺序为7,所以需操作7次
time.sleep(1)
win32api.keybd_event(40,0,0,0)
time.sleep(1)
win32api.keybd_event(40,0,0,0)
time.sleep(1)
win32api.keybd_event(40,0,0,0)
time.sleep(1)
win32api.keybd_event(40,0,0,0)
time.sleep(1)
win32api.keybd_event(40,0,0,0)
time.sleep(1)
win32api.keybd_event(40,0,0,0)
time.sleep(1)
win32api.keybd_event(13,0,0,0)
time.sleep(1)
win32api.keybd_event(13,0,0,0)
cookie操作
简介:
有时候我们需要验证浏览器中cookie是否正确,因为基于真实cookie的测试是⽆法通过⽩盒和集成测试进⾏的。WebDriver提供了操作Cookie的相关⽅法,可以读取、添加和删除cookie信息。
WebDriver操作cookie的⽅法:
- get_cookies() #获得所有cookie信息
- get_cookie(name) #返回字典的key为“name”的cookie信息
- add_cookie(cookie_dict) #添加cookie。
“cookie_dict”指字典对象,必须有‘name’和‘value’两个key,可选的key是‘path’,‘domin’,‘secure’,‘expiry’,‘httponly‘
-name:cookie的名称
-value:cookie对应的值,动态生成
-domain:服务器域名
-expiry:cookie有效终止日期
-path:path属性定义了web服务器上哪些路径下的页面可获取服务器设置的cookie
-httpOnly:防脚本攻击
-secure:在cookies中标记该变量,表明只有当浏览器和web server之间的通信协议为加密认证协议时
- delete_cookie(name,optionsString) #删除cookie信息
“name”是要删除的cookie的名称,“optionsString”是该cookie的选项,⽬前⽀持的选项包括“路径”,“域”
- delete_all_cookies() 删除所有cookie信息
- 例:
from selenium import webdriver
import time
browser = webdriver.Chrome("F:\Chrome\ChromeDriver\chromedriver")
browser.get("http://www.youdao.com")
#1.打印cookie信息
print('=====================================')
print("打印cookie信息为:")
print(browser.get_cookies)
#2.添加cookie信息
dict={'name':"name",'value':'Kaina'}
browser.add_cookie(dict)
print('=====================================')
print('添加cookie信息为:')
#3.遍历打印cookie信息
for cookie in browser.get_cookies():
print('%s----%s\n' %(cookie['name'],cookie['value']))
#4.删除⼀个cookie
browser.delete_cookie('name')
print('=====================================')
print('删除⼀个cookie')
for cookie in browser.get_cookies():
print('%s----%s\n' %(cookie['name'],cookie['value']))
print('=====================================')
print('删除所有cookie后:')
#5.删除所有cookie,⽆需传递参数
browser.delete_all_cookies()
for cookie in browser.get_cookies():
print('%s----%s\n' %(cookie['name'],cookie['value']))
time.sleep(3)
browser.close()
登录操作
简介:
在实际的web应用中,用户登录时通常要求用户输入验证码,验证码大多分为四类:识图验证码、计算验证码、滑块验证码以及语音验证码,这里介绍识图验证码。
两种解决方案:
1、通过cookies绕过登录
- 原理:先通过一次手动的登录,登录成功后可以获取到对应的cookies,之后,在下一次的访问中,只需要向driver对象添加cookies,即可绕过登录和验证码过程,直接登录。
- 实例:selenium自动化 | 通过获取cookies登录
- 更多关于cookies的操作:十三、cookie操作
2、借助识别工具识别验证码
- 百度AI开放平台:http://ai.baidu.com/
- 操作方法简介
- 使用百度账号登录百度AI开放平台,进入控制台,选择文字识别,点击创建应用
- 点击管理应用,获取访问百度服务所需的验证信息AppID、API Key、Secret Key
- 安装使用python SDK:pip install baidu-aip
- 识别过程简介
- 截取当前显式验证码的网页图片
- 裁剪网页图片得到验证码大图
- 调用百度AI平台识别验证码
JavaScript操作
简介:
虽然WebDriver提供了操作浏览器的前进和后退⽅法,但对于浏览器滚动条并没有提供相应的操作⽅法。在这种情况下,就可以借助JavaScript来控制浏览器的滚动条。
WebDriver提供了此方法执⾏JavaScript代码:
- execute_script()
js代码的相关操作:
- 输入操作
- "document.getElementById(' ').value=' '; " #
- 单击操作
- "document.getElementById(' ').click(); " #
- 焦点操作
- e=driver.find_element_by_id("su")
- driver.execute_script("arguments[0].blur();" , e) # 移除焦点操作
- driver.execute_script("arguments[0].blur();" , e) # 赋予焦点操作
- 浏览器操作
- "window.open(url);" # 打开浏览器
- "window.resizeTo(width,height);" # 绝对方法,设置浏览器窗口的实际大小,即“变化到多少”
- "window.resizeBy(width,height);" # 相对方法,在当前大小上增加所指定的参数值,即“变化了多少”
- "window.moveTo(width,height);" # 绝对方法,设置窗口新的绝对位置
- "window.moveBy(width,height);” # 相对方法,在当前位置上增加所指定的参数值
- "history.forword();“ # 控制浏览器前进
- "history.back();” # 控制浏览器后退
- “history.go(number | url);"
- 参数可以是数字number,即要访问的url在history的url列表中的相对位置。(-1表示上一个页面,1表示前进一个页面,0则是刷新页面)
- 参数可以是一个字符串,字符串必须是局部或完整的url,该函数会去匹配包含字符串的第一个url
- “history.go(0);” , "location.reload();" , "location=location;" , "location.assign(location);" , "location.replace(location);" # 刷新浏览器
- “window.close();” # 关闭浏览器
- 鼠标操作
- 创建事件
- document.createEvent('MouseEvents');
- 初始化返回的的时间对象
- event.initMouseEvent(type,canBuble,cancelable,view,detail,screenX,screenY,clientY,ctrlKey,altKey,metaKey,button,relatedTarget);
- type:click(单击),dbclick(双击),mouseover(鼠标悬停)
- 触发事件
- arguments[0].dispatchEvent()
- 例:
e = driver.find_element_by_name("name")
js =
"""
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click',true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);
arguments[0].dispatchEvent(event);
"""
driver.execute_script(js,e)
- 创建事件
- 滚动条操作
- 水平滚动
- "document.documentElement.scrollLeft = 100" # scrollLeft的初始值为0,最初显示页面最左边的内容,随数值变大,向右滑动
- 垂直滚动
- "document.documentElement.scrollTop = 100" # scrollTop的初始值为0,随数值变大,向下滑动
- 滚动到指定坐标
- "window.scrollTo(x,y)"
- "document.documentElement.scrollTo(x,y)"
- 滚动到指定的像素数
- "window.scrollBy(x,y)"
- "document.documentElement.scrollBy(x,y)"
- 滚动页面元素到可视区域
- "documents[0].scrollIntoView()"
- 水平滚动
- HTML视频操作
- 加载
- driver.execute_script("return arguments[0].load()",video)
- 播放
- driver.execute_script("return arguments[0].play()",video)
- 暂停
- driver.execute_script("return arguments[0].pause()",video)
- 例:
driver.get('https://www.w3school.com.cn/tiy/t.asp?f=html_video')
driver.switch_to_frame('iframeResult')
video=driver.find_element_by_xpath('/html/body/video')
video.click()
driver.execute_script('return arguments[0].load()',video)
driver.execute_script('return arguments[0].play()',video)
driver.execute_script('return arguments[0].pause()',video)
- 加载
窗⼝截图
简介:
⾃动化⽤例是由程序去执⾏的,因此有时候打印的错误信息并不⼗分明确。如果在脚本执⾏出错的时候能对当前窗⼝截图保存,那么通过图⽚就可以⾮常直观地看出出错的原因。
WebDriver提供了截图函数get_screenshot_as_file()来截取当前窗⼝:
- get_screenshot_as_file(self, filename) #⽤于截取当前窗⼝,并把图⽚保存到本地
from selenium import webdriver
from time import sleep
driver =webdriver.Firefox(executable_path ="F:\GeckoDriver\geckodriver")
driver.get('http://www.baidu.com')
driver.find_element_by_id('kw').send_keys('selenium')
driver.find_element_by_id('su').click()
sleep(2)
#1.截取当前窗⼝,并指定截图图⽚的保存位置
driver.get_screenshot_as_file("D:\\baidu_img.jpg")
driver.quit()
python模块详解 | selenium(持续更新中)的更多相关文章
- yii 核心类classes.php详解(持续更新中...)
classes.php在yii运行的时候将被自动加载,位于yii2文件夹底下. <?php /** * Yii core class map. * * This file is automati ...
- Java 关键字详解(持续更新中)
abstract: 表明类或者成员方法具有抽象熟悉. 修饰类,抽象类: 抽象类不能被实例化: 抽象类中可以有属性.方法.构造,都是用来给子类继承的: ...
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
- # OpenGL常用函数详解(持续更新)
OpenGL常用函数详解(持续更新) 初始化 void glutInit(int* argc,char** argv)初始化GULT库,对应main函数的两个参数 void gultInitWindo ...
- python模块详解 | unittest(单元测试框架)(持续更新中)
目录: why unittest? unittest的四个重要概念 加载测试用例的三个方法 自动加载测试用例 忽略测试和预期失败 生成html测试报告 why unittest? 简介: Unitte ...
- kubernetes 控制器详解【持续完善中】
目录 资源创建详解 一:Pod及常用参数 1.简介 2.模板 3.删除pod 4.设置Pod主机名 5.镜像拉取策略(ImagePullPolicy) 二:RC 1.简介 2.模板 三:Deploym ...
- MYSQL EXPLAIN执行计划命令详解(支持更新中)
本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 本篇是根据官网中的每个一点来翻译.举例.验证的:英语不好,所 ...
- python模块详解 random os
random模块 常用方法 random.random() 随机产生一个小于1的浮点数 import random print(random.random()) #0.4153761818276826 ...
- python模块详解
什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的代码(.p ...
随机推荐
- tcp/ip原理/三次握手/四次挥手
@ tcp/ip原理 1.1 tcp/ip三次握手 1.1.1 建立过程说明 a) 由主机A发送建立TCP连接的请求报文, 其中报文中包含seq序列号, 是由发送端随机生成的, 并且还将报文中SY ...
- STL——容器概述
在实际的开发过程中,数据结构本身的重要性完全不逊于算法的重要性,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要. 试想:如同栈一样的一条死胡同里停车,这样的效率会很高吗? 经典的数 ...
- Mysql锁机制--悲观锁和乐观锁
1. 悲观锁简介 悲观锁(Pessimistic Concurrency Control,缩写PCC),它指的是对数据被外界修改持保守态度,因此,在整个数据处理过程中, 将数据处于锁定状态.悲观锁的实 ...
- 来感受Linux命令行的“真香定律”
Shell看起来只是一个黑黑的命令框,刚开始接触会觉得很丑,毕竟与Win/Mac的华丽界面比起来,命令行终端直接可以丑拒了.但是,实际上它的功能要强大得多,毕竟Linux一开始就是广泛应用于服务器,通 ...
- 小兔子有颗玻璃心A版【转】
作者:诸君平身链接:https://www.zhihu.com/question/49179166/answer/116926446来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- 【英雄帖】FreeRedis 邀请您一起优化项目。
嘿!各位!自 FreeRedis 开库以来,相继出现了很多贡献者,我们正在对 FreeRedis 的各功能模块做优化,这并不意味着现版的 FreeRedis 有问题,我们只是希望在某些方面做得更好.如 ...
- 图解JanusGraph系列 - JanusGraph指标监控报警(Monitoring JanusGraph)
大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步(超链):图数据库系列-文章总目录 源码分析相关可查看github(码文不易,求个sta ...
- [EF] - Code First处理Clustered Index
Clustered Index <=>集群索引: http://msdn.microsoft.com/en-us/library/ms177443.aspx 由于其特殊性,使得每个tabl ...
- 深入理解Spring Security授权机制原理
原创/朱季谦 在Spring Security权限框架里,若要对后端http接口实现权限授权控制,有两种实现方式. 一.一种是基于注解方法级的鉴权,其中,注解方式又有@Secured和@PreAuth ...
- 【electron+vue3+ts实战便笺exe】二、electron+vue3开发内容
不要让自己的上限成为你的底线 本来以为有万字的..没想到才堪堪近6000字.为了水文的嫌疑,只挑了重点的地方讲,比如component内的组件就挑了右键弹窗去说明,建议在看本文的时候边查看项目,有不懂 ...