3.
标签内.
(2)表格的元素定位可以用xpath定位方式,比如:.//*[@id='myTable']/tbody/tr[2]/td[1]
需要说明的是,这里定位的格式是固定的,只需改tr和td后面的数字就可以了.如第二行第一列tr[2]td[1].
<例>from selenium import webdriver
url='file:///C:/Users/Gloria/Desktop/table.html'
driver=webdriver.Firefox()
driver.get(url)
t=driver.find_element_by_xpath(".//*[@id='myTable']/tbody/tr[2]/td[1]")
print t.text
13.加载Firefox配置:
(1)加载Chrome配置方法就是将username改成自己电脑的名字即可(不要用中文)
<例>'--user-data-dir=C:\Users\username\AppData\Local\Google\Chrome\User Data'
#coding:utf-8
from selenium import webdriver
#加载chrome配置
option=webdriver.ChromeOptions()
option.add_argument('--user-data-dir=C:\Users\Gloria\AppData\Local\Google\Chrome\User Data')
driver = webdriver.Chrome(chrome_options=option)
driver.implicitly_wait(30)
driver.get("http://www.cnblogs.com/yoyoketang/")
(2)wap测试:
<例>#coding:utf-8
from selenium import webdriver
option=webdriver.ChromeOptions()
#伪装iphone登录:
option.add_argment('--user-agent=iphone')
#伪装android登录:
option.add-argment('--user-agent=android')
driver=webdriver.Chrome(chrome_options=option)
driver.get('http://www.taobao.com')
14.富文本(richtext):
<例># coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
profileDir = r'C:\Users\Gloria\AppData\Roaming\Mozilla\Firefox\Profiles\1x41j9of.default'
profile = webdriver.FirefoxProfile(profileDir)
driver = webdriver.Firefox(profile)
bolgurl = "http://www.cnblogs.com/"
yoyobolg = bolgurl + "yoyoketang"
driver.get(yoyobolg)
driver.find_element_by_id("blog_nav_newpost").click()
time.sleep(5)
edittile = u"Selenium2+python自动化23-富文本"
editbody = u"这里是发帖的正文"
driver.find_element_by_id("Editor_Edit_txbTitle").send_keys(edittile)
driver.switch_to.frame("Editor_Edit_EditorBody_ifr")
driver.find_element_by_id("tinymce").send_keys(Keys.TAB)
driver.find_element_by_id("tinymce").send_keys(editbody)
15.非input文件上传(SendKeys):
(1)sendkeys安装步骤:
1.sendkeys安装:
输入命令:pip install sendkeys.
2.如果安装的时候报错:micsoft visual c++ is required.Get it from http://aka.ms/vcpython27.的时候,只需要按照 给定的路径http://aka.ms/vcpython27下载文件即可,然后一路安装即可。
3.如果出现successfully installed sendkeys_0.3字样的时候,则代表文件安装成功!
<例># coding:utf-8
from selenium import webdriver
import SendKeys
import time
# 加载Firefox配置
profileDir = r'C:\Users\xxxAppData\Roaming\Mozilla\Firefox\Profiles\1x41j9of.default'
profile = webdriver.FirefoxProfile(profileDir)
driver = webdriver.Firefox(profile)
# 加载Chrome配置
option = webdriver.ChromeOptions()
option.add_argument('--user-data-dir=C:\Users\xxxAppData\Local\Google\Chrome\User Data')
driver = webdriver.Chrome(chrome_options=option)
driver.implicitly_wait(30)
driver.get("http://www.cnblogs.com/yoyoketang/")
driver.find_element_by_link_text("新随笔").click()
time.sleep(3)
# 点开编辑器图片
driver.find_element_by_css_selector("img.mceIcon").click()
time.sleep(3)
# 定位所有iframe,取第二个
iframe = driver.find_elements_by_tag_name('iframe')[1]
# 切换到iframe上
driver.switch_to_frame(iframe)
# 文件路径
time.sleep(2)
driver.find_element_by_class_name("qq-upload-button").click()
# driver.find_element_by_name("file").click() # 这里点文件上传按钮也是一个坑,我用它父元素定位了,参 考上面一行
time.sleep(5)
# SendKeys方法输入内容
SendKeys.SendKeys("D:\\test\\jie1\\blog\\12.png") # 发送文件地址
time.sleep(1)
SendKeys.SendKeys("{ENTER}") # 发送回车键
time.sleep(1)
SendKeys.SendKeys("{ENTER}") # 因为我的电脑是搜索输入法,所以多按一次回车
driver.quit()
16.文件上传(send_keys):
文件上传是web页面上很常见的一个功能,一般分两个场景:一种是input标签,这种可以用selenium提供的send_keys()方法轻 松解决;另外一种非input标签实现起来比较困难,可以借助autoit工具或者SendKeys第三方库。
方法一:识别上传按钮
1.点开博客园编辑器里的图片上传按钮,弹出”上传本地图片”框。
2.用firebug查看按钮属性,这种上传图片按钮有个很明显的标识,它是一个input标签,并且type属性的值为file。只要 找到这两个标识,我们就可以直接用send_keys()方法上传文件了。
方法二:定位iframe
1.这里定位图片上传按钮情况有点复杂,首先它是在iframe上。
2.这个iframe的id是动态的,且没有name属性,其它属性也不是很明显。
3.通过搜索发现,这个页面上有两个iframe,需要定位的这个iframe是处于第二个位置。
4.可以通过标签定位所有的iframe标签,然后取对应的第几个就可以了。
<例> #coding:utf-8
from selenium import webdriver
import time
profileDir=r'C:\Users\Gloria\AppData\Roaming\Mozilla\Firefox\Profiles\1x41j9of.default'
profile=webdriver.Firefoxprofile(profiledir)
driver=webdriver.Firefox(profile)
driver.implicitly_wait(30)
driver.get("http://www.cnblogs.com/yoyoketang/")
driver.find_element_by_link_text("新随笔").click()
time.sleep(3)
#点开编辑图片
driver.find_element_by_css_selector("img.mceIcon").click()
time.sleep(3)
#定位所有的iframe,取第二个
iframe=driver.find_elements_by_tag_name('iframe')[1]
#切换到iframe上
driver.switch_to_frame(iframe)
#文件路径
driver.find_element_by_name('file').send_keys
17.获取元素属性;
(1)title的获取方法;
<例> #coding:utf-8
from selenium import webdriver
import time
driver=webdriver.Firefox()
driver.implicitly_wait(10)
driver.get(“http:www.baidu.com”)
time.sleep(2)
title=driver.title
print title
(2)通过driver.text获取到文本;
<例> #coding:utf-8
from selenium import webdriver
import time
driver=webdriver.Firefox()
driver.implicitly_wait(10)
driver.get(“http:www.baidu.com”)
time.sleep(2)
title=driver.title
print title
text=driver.find_element_by_id(“setf”).text
print text
(3)获取元素的标签
<例>获取百度输入框的标签属性
tag=driver.find_element_by_id(“kw”).tag_name
print tag
(4)获取元素的其它属性;
获取其它属性方法:get_attribute("属性"),这里的参数可以是class、name等任意属性.
<例>获取百度输入框的class属性;
name=driver.find_element_by_id(“kw”).get_attribute(“class”)
print name
(5)获取输入框内的文本值;
如果在百度输入框输入了内容,这里输入框的内容也是可以获取到的.
<例>获取百度输入框的内容;
driver.find_element_by_id(“kw”).send_keys(“yoyoketang”)
value=drvier.find_element_by_id(“kw”).get_attribute(“value”)
print value
(6)获取浏览器名称;获取浏览器名称很简单,用driver.name就能获取到.
<例>#coding:utf-8
from selenium import webdriver
import time
driver=webdriver.Firefox()
driver.implicitly_wait(10)
driver.get(“http:www.baidu.com”)
time.sleep(2)
title=driver.title
print title
print driver.name
18.爬页面源码(page_source)
(1)有时候通过元素的属性的查找页面上的某个元素,可能不太好找,这时候可以从selenium的page_source方法可以获取到页 面源码。
<例>#coding:utf-8
from selenium import webdriver
import re
driver=webdriver.Firefox()
driver.get(“http://www.cnblogs.com/yoyoketang/”)
page=driver.page_source
print page
(2)re非贪婪模式:
1.这里需导入re模块(正则表达式模块)
2.用re的正则匹配:非贪婪模式
3.findall方法返回的是一个list集合
4.匹配出来之后发现有一些不是url链接,可以筛选下
#“非贪婪匹配”,re.s('.'匹配字符,包括换行符)”
url_list=re.findall('href=\"(.*?)\"',page,re.s)
for url in url_list:
print url
(3)筛选url地址出来
1.加个if语句判断,‘http’在url里面说明是正常的url地址了
2.把所有的url地址放到一个集合,就是我们想要的结果啦.
#“非贪婪匹配”,re.s('.'匹配字符,包括换行符)”
url_list=re.findall('href=\"(.*?)\"',page,re.s)
url_all=[]
for url in url_list:
if "http" in url:
print url
url_all.append(url)
print url_all
19.cookie相关操作:
(1)获取cookies:get_cookies()
1.获取cookies方法直接用:get_cookies()
2.先启动浏览器,获取cookies,打印出来发现是空:[]
3.打开博客首页后,重新获取cookies,打印出来,就有值了.
<例># coding:utf-8
from selenium import webdriver
import time
driver=webdriver.Firefox()
#启动浏览器后获取cookies
print driver.get_cookies()
driver.get("http://www.cnblogs.com/yoyoketang/")
#打开主页后获取cookies
print driver.get_cookies()
(2)登录后的cookies:
1.先登录博客园(这里登录用自己的账号和密码吧)
2.重新获取cookies,发现跟之前获取的不一样了
3.主要是找到这一个cookie,发现它的name和value发生了变化,这就是未登录和已登录的区别了(对比上下两张图)
{u'name': u'.CNBlogsCookie', u'value': u'B7813EBA142142CE88CC8C0B33B239F566xxxx'}
<例>
#登录后获取cookies
url="https://passport.cnbblogs.com/user/signin"
driver.get(url)
driver.implicitly_wait(30)
driver.find_element_by_id("input1").send_keys(u"上海—悠悠")
driver.find_element_by_id("input2").send_keys(u"xxxxx")
driver.find_element_by_id("signin").click()
time.sleep(3)
print driver.get_cookies()
(3)获取指定name的cookie:driver.get_cookie(name)
1.获取cookies发现里面有多个cookie,有时候我们只需要其中的一个,把重要的提出来,比如登录的cookie
2.这里用get_cookie(name),指定对应的cookie的name值就行了,比如博客园的:.CNBlogsCookie
<例># 获取指定的name的cookie
print driver.get_cookie(name=".CNBlogsCookie")
(4)清除指定cookie:delete_cookie()
1.为了进一步验证上一步获取到的就是登录的cookie,可以删除它看看页面什么变化
2.删除这个cookie后刷新页面,发现刚才的登录已经失效了,变成未登录状态了
<例># 清除指定name的cookie
driver.delete_cookie(name="CNBlogsCookie")
print driver.get_cookies()
# 为了验证此cookie是登录的,可以删除后刷新页面
driver.refresh()
(5)清除所有cookies:delete_all_cookies()
清除所有cookies后登录状态也失效了,cookies为空[];
<例># 清除所有的cookie
driver.delete_all_cookies()
print driver.get_cookies()
(6)cookie操作的几个方法
1.get_cookies():获取所有cookies
2.driver.get_cookie(name):获取指定name的cookie:
3.清除指定cookie:delete_cookie()
4.delete_all_cookies():清除所有cookies
5.add_cookie(cookie_dict):添加cookie的值
20.绕过验证码(add_cookie);
验证码这种问题是比较头疼的,对于验证码的处理,不要去想破解方法,这个验证码本来就是为了防止别人自动化登录的。如果 你能破解,说明你们公司的验证码吗安全级别不高,那就需要提高级别了。
对于验证码,要么是让开发在测试环境弄个万能的验证码,如:1234,要么就是尽量绕过去,如本篇介绍的添加cookie的方法。
一、fiddler抓包
1.前一篇讲到,登录后会生成一个已登录状态的cookie,那么只需要直接把这个值添加到cookies里面就可以了。
2.可以先手动登录一次,然后抓取这个cookie,这里就需要用抓包工具fiddler了
3.先打开博客园登录界面,手动输入账号和密码(不要点登录按钮)
4.打开fiddler抓包工具,此时再点博客园登录按钮
5.登录成功后,再查看cookie变化,发现多了两组参数,多的这两组参数就是我们想要的,copy出来,一会有用
二.添加cookie方法:driver.add_cookie()
1.add_cookie(cookie_dict)方法里面参数是cookie_dict,说明里面参数是字典类型。
2.源码官方文档介绍:
add_cookie(self, cookie_dict):
Adds a cookie to your current session.
:Args:
- cookie_dict: A dictionary object, with required keys - "name" and "value";
optional keys - "path", "domain", "secure", "expiry"
Usage:
driver.add_cookie({'name' : 'foo', 'value' : 'bar'})
driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/'})
driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/', 'secure':True})
3.从官方的文档里面可以看出,添加cookie时候传入字典类型就可以了,等号左边的是name,等号右边的是value。
4.把前面抓到的两组数据(参数不仅仅只有name和value),写成字典类型:
{'name':'.CNBlogsCookie','value':'2C3AE01E461B2D2F1572D02CB936D77A053089AA2xxxx...'}
{'name':'.Cnblogs.AspNetCore.Cookies','value':'CfDJ8Mmb5OBERd5FqtiQlKZZIG4HKz_Zxxx...'}
三、cookie组成结构
1.用抓包工具fidller只能看到cookie的name和value两个参数,实际上cookie还有其它参数。
2.cookie参数组成,以下参数是我通过get_cookie(name)获取到的。
cookie ={u'domain': u'.cnblogs.com',
u'name': u'.CNBlogsCookie',
u'value': u'xxxx',
u'expiry': 1491887887,
u'path': u'/',
u'httpOnly': True,
u'secure': False}
name:cookie的名称
value:cookie对应的值,动态生成的
domain:服务器域名
expiry:Cookie有效终止日期
path:Path属性定义了Web服务器上哪些路径下的页面可获取服务器设置的Cookie
httpOnly:防脚本攻击
secure:在Cookie中标记该变量,表明只有当浏览器和Web Server之间的通信协议为加密认证协议时,
浏览器才向服务器提交相应的Cookie。当前这种协议只有一种,即为HTTPS。
四、添加cookie
1.这里需要添加两个cookie,一个是.CNBlogsCookie,另外一个是.Cnblogs.AspNetCore.Cookies。
2.我这里打开的网页是博客的主页:http://www.cnblogs.com/yoyoketang,没进入登录页。
3.添加cookie后刷新页面,接下来就是见证奇迹的时刻了。
# coding:utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.cnblogs.com/yoyoketang")
# 添加cookie
c1 = {u'domain': u'.cnblogs.com',
u'name': u'.CNBlogsCookie',
u'value': u'xxxx',
u'expiry': 1491887887,
u'path': u'/',
u'httpOnly': True,
u'secure': False}
c2 = {u'domain': u'.cnblogs.com',
u'name': u'.Cnblogs.AspNetCore.Cookies',
u'value': u'xxxx',
u'expiry': 1491887887,
u'path': u'/',
u'httpOnly': True,
u'secure': False}
driver.add_cookie(c1) # 添加2个值
driver.add_cookie(c2)
time.sleep(3) # 交流QQ群:232607095
# 刷新下页面就见证奇迹了
driver.refresh()
有几点需要注意:
1.登录时候要勾选下次自动登录按钮。
2.add_cookie()只添加name和value,对于博客园的登录是不成功。
3.本方法并不适合所有的网站,一般像博客园这种记住登录状态的才会适合。
21 JS处理滚动条;
selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了。比如下面的场景:
当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的。这时候需要借助滚动条来拖动 屏幕,使被操作的元素显示在当前的屏幕上。滚动条是无法直接用定位工具来定位的。selenium里面也没有直接的方法去控制 滚动条,这时候只能借助J了,还好selenium提供了一个操作js的方法:execute_script(),可以直接执行js的脚本。
一、JavaScript简介
JavaScript是世界上最流行的脚本语言,因为你在电脑、手机、平板上浏览的所有的网页,以及无数基于HTML5的手机App, 交互逻辑都是由JavaScript驱动的。简单地说,JavaScript是一种运行在浏览器中的解释型的编程语言。
(参考链接;http://www.w3school.com.cn/js/index.asp4)
二、控制滚动条高度
1.滚动条回到顶部:
js="var q=document.getElementById('id').scrollTop=0"
driver.execute_script(js)
2.滚动条拉到底部;
js="var q=document.documentElement.scrollTop=10000"
driver.execute_script(js)
3.这里可以修改scrollTop 的值,来定位右侧滚动条的位置,0是最上面,10000是最底部。
三、横向滚动条
1.有时候浏览器页面需要左右滚动(一般屏幕最大化后,左右滚动的情况已经很少见了)。
2.通过左边控制横向和纵向滚动条;
scrollTo(x, y)js = "window.scrollTo(100,400);"
driver.execute_script(js)
3.第一个参数x是横向距离,第二个参数y是纵向距离
四、Chrome浏览器
1.以上方法在Firefox上是可以的,但是用Chrome浏览器,发现不管用。
2.Chrome浏览器解决办法:
js = "var q=document.body.scrollTop=0"
driver.execute_script(js)
五、元素聚焦
1.虽然用上面的方法可以解决拖动滚动条的位置问题,但是有时候无法确定我需要操作的元素在什么位置,有可能每次打开 的页面不一样,元素所在的位置也不一样,怎么办呢?
2.这个时候我们可以先让页面直接跳到元素出现的位置,然后就可以操作了。同样需要借助JS去实现。
3.元素聚焦:
target = driver.find_element_by_xxxx()
driver.execute_script("arguments[0].scrollIntoView();", target)
六、获取浏览器名称:driver.name
1.为了解决不同浏览器操作方法不一样的问题,可以写个函数去做兼容。
2.先用driver.name获取浏览器名称,然后用if语句做个判断
# coding:utf-8
from selenium import webdriver
driver=webdriver.Firefox()
driver.get(“https://www.baidu.com”)
print driver.name
七、兼容性
1.兼容谷歌和firefox/IE
#回到顶部
def scroll_top():
if driver.name=="chrome"
js="var q=document.body.scrollTop=0"
else:
js="var q=document.documentElement.scrollTop=0"
return driver.execute_script(js)
#拉到底部
def scroll_foot():
if driver.name=="chrome"
js="var q=document.body.scrollTop=10000"
else:
js="var q=document.documentElement.scrollTop=10000"
return driver.execute_script(js)
八、scrollTo函数
--scrollHeight 获取对象的滚动高度。
--scrollLeft 设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离。
--scrollTop 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离。
--scrollWidth 获取对象的滚动宽度。
scrollTo函数不存在兼容性问题,直接用这个函数就可以了;
#滚动到底部
js = "window.scrollTo(0,document.body.scrollHeight)"
driver.execute_script(js)
#滚动到顶部
js = "window.scrollTo(0,0)"
driver.execute_script(js)
22.JS处理富文本;
一、加载配置
1.打开博客园写随笔,首先需要登录,这里为了避免透露个人账户信息,我直接加载配置文件,免登录了。
不懂如何加载配置文件的,看加载firefox配置.
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import keys
import time
profileDir=r'C:\xxx...\Firefox\profiles\1x41j9of.default'
profile=webdriver.Firefoxprofile(profileDir)
driver=webdriver.Firefox(profile)
二、打开编辑界面
1.博客首页地址:bolgurl = "http://www.cnblogs.com/"
2.我的博客园地址:yoyobolg = bolgurl + "yoyoketang"
3.点击“新随笔”按钮,id=blog_nav_newpost
bolgurl= "http://www.cnblogs.com/"
yoyobolg = bolgurl + "yoyoketang"
driver.get(yoyobolg)
driver.find_element_by_id("blog_nav_newpost").click()
三、定位iframe
1.打开编辑界面后先不要急着输入内容,先sleep几秒钟
2.输入标题,这里直接通过id就可以定位到,没什么难点
3.接下来就是重点要讲的富文本的编辑,这里编辑框有个iframe,所以需要先切换
四、js输入中文
1.这里定位编辑正文是定位上图的红色框框位置body部分,也就是id=tinymce
2.定位到之后,用js的方法直接输入,无需切换iframe
3.直接点保存按钮,无需再切回来.
<完整代码>
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
# profileDir路径对应直接电脑的配置路径
profileDir = r'C:\xxx\xxx\AppData\Roaming\Mozilla\Firefox\Profiles\1x41j9of.default'
profile = webdriver.FirefoxProfile(profileDir)
driver = webdriver.Firefox(profile)
bolgurl = "http://www.cnblogs.com/"
yoyobolg = bolgurl + "yoyoketang"
driver.get(yoyobolg)
driver.find_element_by_id("blog_nav_newpost").click()
time.sleep(5)
edittile = u"Selenium2+python自动化23-富文本"
editbody = u"这里是发帖的正文"
driver.find_element_by_id("Editor_Edit_txbTitle").send_keys(edittile)
body = "这里是通过js发的正文内容"
# js处理iframe问题(js代码太长了,我分成两行了)
js = 'document.getElementById("Editor_Edit_EditorBody_ifr")' \
'.contentWindow.document.body.innerHTML="%s"' % body
driver.execute_script(js)
# 保存草稿
driver.find_element_by_id("Editor_Edit_lkbDraft").click()
23 js处理日历控件(修改readonly属性);
<完整代码>
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://kyfw.12306.cn/otn/index/init")
# 去掉元素的readonly属性
js = 'document.getElementById("train_date").removeAttribute("readonly");'
driver.execute_script(js)
# 用js方法输入日期
js_value = 'document.getElementById("train_date").value="2016-12-25"'
driver.execute_script(js_value)
# # 清空文本后输入值
# driver.find_element_by_id("train_date").clear()
# driver.find_element_by_id("train_date").send_keys("2016-12-25")
24.js处理内嵌div滚动条;
一.纵向滚动;
1.这个是div的属性:
2.这里最简单的通过id来定位,通过控制 scrollTop的值来控制滚动条高度
3.运行下面代码,观察页面是不是先滚动到底部,过五秒再回到顶部。(get里面地址 是浏览器打开该页面的地址)
<例># coding:utf-8
from selenium import webdriver
import time
driver=webdriver.Firefox()
driver.get("file:///C:/Users/Gloria/Desktop/div.html")
# 纵向底部
js1=‘document.getElementById("yoyoketang").scrollTop=10000’
driver.execute_script(js1)
time.sleep(5)
# 纵向顶部
js1=‘document.getElementById("yoyoketang").scrollTop=0’
driver.execute_script(js1)
二.横向滚动;
先通过id来定位,通过控制scrollLeft的值来控制滚动条高度.
<例># coding:utf-8
from selenium import webdriver
import time
driver=webdriver.Firefox()
driver.get("file:///C:/Users/Gloria/Desktop/div.html")
# 横向右侧
js3=‘document.getElementById("yoyoketang").scrollLeft=10000’
driver.execute_script(js3)
time.sleep(5)
# 横向左侧侧
js4=‘document.getElementById("yoyoketang").scrollLeft=0’
driver.execute_script(js4)
三.用class属性定位;
js用class属性定位,返回的是一个list对象,这里取第一个就可以了。
注意;element和elements是不一样的.
<例> # coding:utf-8
from selenium import webdriver
import time
driver=webdriver.Firefox()
driver.get("file:///C:/Users/Gloria/Desktop/div.html")
# 获取的class返回的是list对象,取list的第一个
js5=‘document.getElementsByClassName("scroll") [0].scrollTop=10000’
driver.execute_script(js5)
time.sleep(5)
# 控制横向滚动条位置
js6=‘document.getElementsByClassName("scroll") [0].scrollLeft=10000’
driver.execute_script(js6)
有时候很多元素属性都一样时候,就可以用复数定位,取对应的第几个就可以了。
25 js处理多窗口;
js去掉target="_blank"属性
1.第一步为了先登录,我这里加载配置文件免登录了.
2.这里用到js的定位方法,定位该元素的class属性
3.定位到该元素后直接修改target属性值为空.
<例># coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
# 加载配置文件免登录
profileDir = r'C:\Users\Gloria\AppData\Roaming\Mozilla\Firefox \Profiles\1x41j9of.default'
profile = webdriver.FirefoxProfile(profileDir)
driver = webdriver.Firefox(profile)
driver.get("https://www.baidu.com/")
# 修改元素的target属性
js = 'document.getElementsByClassName("mnav")[0].target="";'
driver.execute_script(js)
driver.find_element_by_link_text("糯米").click()
(注意:并不是所有的链接都适用于本方法,本篇只适用于有这个target="_blank" 属性链接情况。)
26 js解决click失效问题:
<例># coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.select import Select
import time
driver = webdriver.Firefox()
url = "https://www.baidu.com"
driver.get(url)
time.sleep(3)
mouse = driver.find_element("link text", "设置")
ActionChains(driver).move_to_element(mouse).perform()
time.sleep(3)
driver.find_element("link text", "搜索设置").click()
time.sleep(3)
s = driver.find_element("id", "nr")
Select(s).select_by_visible_text("每页显示50条")
# 方法一:先点父元素 交流QQ群:232607095
# driver.find_element("id", "gxszButton").click()
# driver.find_element("class name", "prefpanelgo").click()
# 方法二:用js直接去点击 .
js = 'document.getElementsByClassName("prefpanelgo")[0].click();'
driver.execute_script(js)
27.18种定位方法总结:
一、十八种定位方法:
(1)常用的八种元素定位方式:
1.id定位:find_element_by_id(self, id_)
2.name定位:find_element_by_name(self, name)
3.class定位:find_element_by_class_name(self, name)
4.tag定位:find_element_by_tag_name(self, name)
5.link定位:find_element_by_link_text(self, link_text)
6.partial_link定位find_element_by_partial_link_text(self, link_text)
7.xpath定位:find_element_by_xpath(self, xpath)
8.css定位:find_element_by_css_selector(self, css_selector)
(2)这八种是复数形式;
9.id复数定位find_elements_by_id(self, id_)
10.name复数定位find_elements_by_name(self, name)
11.class复数定位find_elements_by_class_name(self, name)
12.tag复数定位find_elements_by_tag_name(self, name)
13.link复数定位find_elements_by_link_text(self, text)
14.partial_link复数定位find_elements_by_partial_link_text(self, link_text)
15.xpath复数定位find_elements_by_xpath(self, xpath)
16.css复数定位find_elements_by_css_selector(self, css_selector)
(3)这两种就是快失传了的;
17.find_element(self, by='id', value=None)
18.find_elements(self, by='id', value=None)
二、element和elements傻傻分不清
1.element方法定位到是是单数,是直接定位到元素
2.elements方法是复数,这个学过英文的都知道,定位到的是一组元素,返回的是 list队列.
3.可以用type()函数查看数据类型.
<参考代码>
# coding:utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
# 这里是定位的单个id
element = driver.find_element_by_id("kw")
print type(element)
print element
# 这里定位是多个class
elements = driver.find_elements_by_class_name("mnav")
print type(elements)
print elements
# 这里用的css语法
s = driver.find_elements("css selector", ".mnav")
# '地图'在第四个位置
print s[3].text
s[3].click()
# 这个写法也是可以的
# driver.find_elements("css selector", ".mnav")[3].click()
28.查看webdriver API(带翻译)
一、pydoc
1.到底什么是pydoc? ,这个是准确的解释:Documentation generator and online help system. pydoc是Python自带的模块,主要用于从python模块中自动生成文 档,这些文档可以基于文本呈现的、也可以生成WEB页面的,还可以在服务器上以 浏览器的方式呈现!简而言之,就是帮你从代码和注释自动生成文档的工具。
2.举个栗子,我需要查看python里面open函数的功能和语法,打开cmd,输入:python -m pydoc open
3.-m参数:python以脚本方法运行模块;
>>python -m pydoc open
二、启动server;
1.打开cmd命令行,输入:python -m pydoc -p 6666
2.-p参数:这个表示在本机上启动服务
3.6666参数:这个是服务端口号,随意设置
打开后,界面会出现一个地址:http://localhost:6666/,在浏览器直接打开。
三、浏览器查看文档
1.在浏览器输入:http://localhost:6666/
2.Built-in Moudles :这个是python自带的模块.
四、webdriver API:
1.找到这个路径:python2.7\lib\site-packages,点开selenium
2.打开的selenium>webdriver>firefox>webdriver,最终路径: http://localhost:6666/selenium.webdriver.firefox.webdriver.html
3.最终看到的这些就是selenium的webdriver API帮助文档啦.
29.练习题;
一.去掉页面动态窗.
1、alert弹窗;
这种弹窗是最简单的一种,Selenium里有自带的方法来处理它,用switch_to.alert 先定位到弹窗,然后使用一系列方法来操作:
accept - 点击【确认】按钮
dismiss - 点击【取消】按钮(如有按钮)
send_keys - 输入内容(如有输入框)
这里举一个菜鸟教程上的一个例子:
http://www.runoob.com/try/try.php?filename=tryjs_alert,
在页面左边点击【显示警告框】就会弹出一个alert弹窗:
我们用以下代码就能实现切换至弹窗并点击【确定】按钮的效果:
al = driver.switch_to_alert() al.accept()
这里这个switch_to_alert()其实是旧写法,照理应该是用switch_to.alert(),但是 新写法却会报错,目前猜测是版本问题,可能不支持新写法,这里就先用旧写法。
<例># encoding:utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.runoob.com/try/try.php?filename=tryjs_alert") driver.switch_to.frame("iframeResult")
driver.find_element_by_xpath("html/body/input").click()
time.sleep(1) al = driver.switch_to_alert()
time.sleep(1) al.accept()
2、自定义弹窗
由于alert弹窗不美观,现在大多数网站都会使用自定义弹窗,使用Selenium自带的 方法就驾驭不了了,此时就要搬出JS大法。这里举一个新世界教育官网首页的例子 (http://sh.xsjedu.org):
<例># encoding:utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://sh.xsjedu.org/")
time.sleep(1)
js='document.getElementById ("doyoo_monitor").style.display="none";'
driver.execute_script(js)
二.定位百度-更多产品;
<例># coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Firefox()
url = "https://www.baidu.com"
driver.get(url)
driver.maximize_window()
time.sleep(2)
e = driver.find_element_by_link_text("更多产品")
ActionChains(driver).move_to_element(e).perform()
time.sleep(1)
# ele = driver.find_element_by_name("tj_more")
# 经确认,是可以定位到元素的
# print ele.text
# 这一步点击失效了
# ele.click()
# js大法好,完美解决ckick失效问题
js = "document.getElementsByName('tj_more')[0].click()"
driver.execute_script(js)
三.获取百度联系词;
(1)定位输入框联想词
1.首先在百度输入框输入关键词,如:博客,然后输入框下方会自动匹配出关键词。
2.这时候可以用firebug工具定位到联想出来的词,可以看到下方匹配出来的词都有共同的class属性,这时候就可以全部定 位到了。
(2)打印全部匹配出来的词,可以通过get_attribute()方法获取到文本信息
(3)点击其中一个
1.点击其中的一个联想词,如:第二个
2.这里可以先加一个判断,如果获取到了就点击,没获取到就不点击了,以免抛异常。
(如果想依次点击,用for循环就可以了)
<例>
# coding:utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
time.sleep(1)
driver.find_element_by_id("kw").send_keys(u"博客")
# 获取百度输入框的
time.sleep(1)
bd = driver.find_elements_by_class_name("bdsug-overflow")
for i in bd:
print i.get_attribute("data-key")
# 点击其中的一个,如:第二个
if len(bd) > 1:
bd[1].click()
# 打印当前页面url
print driver.current_url
else:
print "未获取到匹配的词"
30.js几种定位方法总结;
一、以下总结了5种js定位的方法
除了id是定位到的是单个element元素对象,其它的都是elements返回的是list对象.
1.通过id获取
document.getElementById(“id”)
2.通过name获取
document.getElementsByName(“Name”)
返回的是list
3.通过标签名选取元素
document.getElementsByTagName(“tag”)
4.通过CLASS类选取元素
document.getElementsByClassName(“class”)
兼容性:IE8及其以下版本的浏览器未实现getElementsByClassName方法
5.通过CSS选择器选取元素
document.querySelectorAll(“css selector")
兼容性:IE8及其以下版本的浏览器只支持CSS2标准的选择器语法
二、id定位
1.定位博客首页的管理按钮:id="blog_nav_contact"
2.js的定位语法里面id定位获取的是单个元素对象,可以直接用click()方法点击元素.
三、class定位
1.js里面class定位获取到是是一个list列表对象.
2.操作元素的话通过下标取对应的第几个值,如果只用一个那就取下标[0].
3.定位到输入框,可以直接用value="xxx"方法输入内容.
4.ByName和ByTagName跟上面class一样,都是定位的一组元素.
四、CSS选择器
1.css选择器定位到的也是一组元素,语法跟前面学到的css语法是一样的.
<例>
# coding: utf-8
from selenium import Webdriver
import time
driver = webdriver.Firefox()
driver.get("http://cnblogs.com/yoyoketang")
#定位首页管理按钮:id=blog_nav_contact
js1 = 'document.getElementById("blog_nav_contact")'.click;'
driver.execute_script(js1)
#输入账号
js2 = 'document.getElementsByClassName("input-text")[0].value="悠悠";'
driver.execute_script(js2)
#输入密码
js3 = 'document.getElementsByClassName("input-text")[1].value="xxx";'
driver.execute_script(js3)
#勾选记住密码
js4 = 'document.getElementsByName("remember_me")[0].click();'
driver.execute_script(js4)
#点击登录按钮
js5 = 'document.querySelectorAll(#signin)[0].click();'
driver.execute_script(js5)
31.定位的坑:class属性有空格.
有些class属性中间有空格,如果直接复制过来定位是会报错的InvalidSelectorException: Message:
The given selector u-label f-dn is either invalid or does not result in a WebElement. The following error occurred:
InvalidSelectorError: Compound class names not permitted.这个报错意思是说定位语法错了。
一、定位带空格的class属性
1.以126邮箱为例:http://mail.126.com/,定位账号输入框.
2.如果直接复制过来用class属性定位是会报错的.
二、class属性科普
1.class属性中间的空格并不是空字符串,那是间隔符号,表示的是一个元素有多个class的属性名称,在整个HTML文档 ,使用CSS中的同一个class类可能是一个或多个!
(class属性是比较特殊的一个,除了这个有多个属性外,其它的像name,id是没多个属性的)
2.想补习html基础知识的可以参考菜鸟教程:http://www.runoob.com/html/html-attributes.html
三、class定位
既然知道class属性有空格是多个属性了,那定位的时候取其中的一个就行(并且要唯一),也就是说class="j- inputtext dlemail",取j-inputtext 和dlemail都是可以的,这样这个class属性在页面上唯一就行.
那么问题来了:如何才知道这个元素的某个属性是不是在页面上是唯一的呢?
四、判断元素唯一性
F12切换到HTML界面,在搜索框输入关键字搜索,如:j-inputtext,然后按回车搜索,看页面上有几个class属性中有 j-inputtext这个属性的,就知道是不是唯一的了。
五、class属性不唯一怎么办
如果这个class的多个属性都不是唯一的咋办呢,元素不唯一也不用怕,可以用复数定位,把所有的相同元素定位出来 ,按下标取第几个就行。
六、css定位
1.css来定位class属性的元素前面加个点(.)就行,然后空格变成点(.)就能定位了.
2.当然css也可以取class属性的其中一个属性(页面上唯一的)来定位,定位方法是灵活多变的.
<参考代码>
# coding:utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://mail.126.com/")
driver.implicitly_wait(20)
driver.switch_to.frame("x-URS-iframe")
# 方法一:取单个class属性
driver.find_element_by_class_name("dlemail").send_keys("yoyo")
driver.find_element_by_class_name("dlpwd").send_keys("12333")
# 方法二:定位一组取下标定位(乃下策)
# driver.find_elements_by_class_name("j-inputtext")[0].send_keys("yoyo")
# driver.find_elements_by_class_name("j-inputtext")[1].send_keys("12333")
# 方法三:css定位
# driver.find_element_by_css_selector(".j-inputtext.dlemail").send_keys("yoyo")
# driver.find_element_by_css_selector(".j-inputtext.dlpwd").send_keys("123")
# 方法四:取单个class属性也是可以的
# driver.find_element_by_css_selector(".dlemail").send_keys("yoyo")
# driver.find_element_by_css_selector(".dlpwd").send_keys("123")
32.jquery定位(简直逆天)
一、jquery搜索元素;
1.按F12进控制台
2.点全部按钮
3.右侧如果没出现输入框,就点下小箭头按钮
4.输入框输入jquery定位语法,如:$("#input1")
5.点运行按钮
6.左边会出现定位到的元素,如果有多个会以list列表的形式展示出。
二、jquery定位语法;
1.jquery语法可以学下w3school的教程:http://www.w3school.com.cn/jquery/jquery_syntax.asp
2.格式如下:
$(selector).action()
--selector:这里的定位语法和css的定位语法是一致的,如:id就是#,class就是点(.),tag标签名前面就无符号
--action:这个是定位元素之后的操作行为事件,如click.
三、jquery行为;
1.发送文本语法:$(selector).val(输入文本的值)
2.清空文本语法:$(selector).val('') # 空字符串,两个单引号
3.点击按钮:$(selector).click()
<参考代码>
# coding:utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("https://passport.cnblogs.com/user/signin")
driver.implicitly_wait(20)
# 输入账号
username = "$('#input1').val('上海-悠悠')"
driver.execute_script(username)
# 清空文本
# time.sleep(5)
# clear = "$('#input1').val('')"
# driver.execute_script(clear)
# 输入密码
psw = "$('#input2').val('yoyo')"
driver.execute_script(psw)
# 点击登录按钮
button = "$('#signin').click()"
driver.execute_script(button)
你可能感兴趣的:(WEB自动化详解)
Vue.js 模板语法全解析:从基础到实战应用
予安灵
前端 vue.js 前端 javascript vue生命周期 vue指令 vue项目结构 vue插值
引言在Vue.js的开发体系中,模板语法是构建用户界面的核心要素,它让开发者能够高效地将数据与DOM进行绑定,实现动态交互效果。通过对《Vue.js快速入门实战》中关于Vue项目部署章节(实际围绕Vue模板语法展开)的深入研读,我们将全面剖析Vue项目结构、应用程序实例、生命周期、插值、指令以及自定义指令等关键内容,并通过实战案例加深理解。1.Vue项目详解项目目录结构以常见的vite-app项目
Python strip() 方法详解:用途、应用场景及示例解析(中英双语)
阿正的梦工坊
Python python 开发语言
Pythonstrip()方法详解:用途、应用场景及示例解析在Python处理字符串时,经常会遇到字符串前后存在多余的空格或特殊字符的问题。strip()方法就是Python提供的一个强大工具,专门用于去除字符串两端的指定字符。本文将详细介绍strip()的用法、适用场景,并通过多个示例解析其应用。1.strip()方法简介strip()方法用于去除字符串两端的指定字符(默认为空格和换行符)。它的
StockTV 全球股票、外汇、期货、加密货币 API 接口文档详解
CryptoRzz
python 金融 数据分析 java websocket
概述StockTV提供了全球范围内的股票、外汇、期货和加密货币的实时数据接口,支持HTTP和WebSocket两种对接方式。本文将详细介绍如何使用StockTV的API接口获取实时数据,并重点介绍印度数据源的使用。接口文档1.获取Key在使用StockTV的API接口之前,您需要先获取一个Key。请通过以下方式联系我们获取Key:联系我们获取Key2.调用API在调用API时,请将获取到的Key添
Java后端开发技术详解
小二爱编程·
java 开发语言
Java作为一门成熟的编程语言,已广泛应用于后端开发领域。其强大的生态系统和广泛的支持库使得Java成为许多企业和开发者的首选后端开发语言。随着云计算、微服务架构和大数据技术的兴起,Java后端开发的技术栈也不断演进。本文将详细介绍Java后端开发的核心技术,包括Java基础、常见框架、数据库操作、缓存技术、异步编程等。1.Java基础:理解面向对象的编程Java是一种面向对象的编程语言,面向对象
「MySQL」日期时间格式化函数 DATE_FORMAT() 的使用详解
m0_74823827
mysql adb android
目录一、DATE_FORMAT()语法二、格式化字符串详解三、常见日期时间格式组合四、业务场景五、总结一、DATE_FORMAT()语法DATE_FORMAT()是MySQL中用于格式化日期时间的函数:语法:DATE_FORMAT(date,format_string)date:需要格式化的日期化时间值,一般是需要被格式化的日期时间类型(datetime类),但也可以是日期时间形式的字符串form
SQL-触发器(trigger)的详解以及代码演示
m0_74823827
面试 学习路线 阿里巴巴 sql 数据库 服务器
一、触发器的概念触发器是一种特殊的存储过程,但是触发器不存在输入和输出参数,所以不能被显式的去调用,而是与特定的表相关联,当表中的数据发生变化时,触发器被激活并执行其定义的SQL代码。触发器可以是行级触发器(针对每一行数据变化)或语句级触发器(针对整个SQL语句的变化),行级触发器允许对每一行单独处理,而语句级触发器则在整个操作完成后执行一次。触发器的功能强化约束:触发器能够实现比CHECK语句更
MySQL 中 int (1) 和 int (10) 的区别详解
阿贾克斯的黎明
游戏开发 mysql 数据库
目录MySQL中int(1)和int(10)的区别详解在MySQL数据库的使用过程中,我们创建数据表时经常会用到整数类型,比如int。而细心的开发者可能会注意到,int后面可以跟一个数字,像int(1)和int(10),这两者到底有什么区别呢?今天我们就来深入探讨一下。在MySQL中,int类型后面括号里的数字M,代表的是显示宽度,最大取值为255。需要明确的是,这个显示宽度和该类型可以存储的范围
前端开发:这就是终点吗?
前端javascript
ReactHook深入浅出CSS技巧与案例详解vue2与vue3技巧合集VueUse源码解读让我们重新回到2021年后远程办公风潮兴起的日子,那时候,程序员岗位炙手可热。机会遍地都是,你甚至只需参加少量培训,通过面试后便能轻松收获年薪超15万的工作,还有余暇拍摄一段《程序员的一天》上传网络。经过短短一年左右的培训,你便踏上了年薪六位数的职业道路——那时候,当程序员似乎是一个人人羡慕的理想职业。然而
深入理解 Vue3 中的 Reflect 和 Proxy 使用
写完这行代码打球去
# vue vue.js 前端 javascript
Proxy详解讲到Proxy对象相信大家都肯定很熟悉,vue3的响应式原理就是以此为基础的。Proxy对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。Proxy语法简要介绍constp=newProxy(target,handler)handler常用方法get-拦截对象属性的读取操作set-拦截对象属性的设置操作has-拦截属性查询操作delet
【QT入门】 Qt槽函数五种常用写法介绍
不吃~香菜
QT入门 qt 开发语言 槽函数 信号槽
声明:该专栏为本人学习Qt知识点时候的笔记汇总,希望能给初学的朋友们一点帮助(加油!)往期回顾:【QT入门】实现一个简单的图片查看软件-CSDN博客【QT入门】图片查看软件(优化)-CSDN博客【QT入门】lambda表达式(函数)详解-CSDN博客【QT入门】Qt槽函数五种常用写法介绍一、信号槽基本概念Qt的信号槽是一种用于处理事件和通信的机制,是Qt框架中的一个重要特性。信号槽机制使得对象之间
Java中卫语句的设计思想
而为.
java 服务器 开发语言
卫语句(GuardClauses)是一种通过提前返回简化条件嵌套、提升代码可读性的编程技巧。其核心思想是优先处理异常或边界情况,让主逻辑保持扁平化。以下是deepseek做出的设计思想详解:核心设计原则FailFast(快速失败)在函数入口处立即检查非法参数或无效状态,若不符合条件则提前终止(如返回、抛异常),避免后续无效操作。减少嵌套层级用卫语句替换多层if-else嵌套,将代码从“箭头型”结构
C# 派生 详解
千亦学不会编程
c# java 开发语言
1.1派生继承设计的目的:经常需要扩展现有类型来添加功能(行为和数据)。定义派生类要在类标识符后添加冒号,接着添加基类名称。注意:1.通过继承,基类的每个成员都出现在派生类构成的链条中。2.除非明确指定基类,否则所有类都默认从object派生。写法:publicclassContact:PdaItem{}
[前端面试场景题]虚拟列表
GISer_Jinger
前端 面试
嗯,用户问的是“前端虚拟列表详解”,我需要详细回答这个问题。首先,我得先理解虚拟列表的概念和用途。根据搜索结果,虚拟列表主要用于优化长列表的渲染性能,特别是在处理大量数据时。用户可能想知道它的核心原理、实现方法以及实际应用场景。看网页1提到虚拟列表的定义和关键点,只渲染视口内的数据项,减少DOM节点。网页2和网页4都给出了具体的Vue和原生JS实现案例,比如动态计算起始和结束索引,使用transf
OpenCV ML 模块使用指南
ice_junjun
OpenCV opencv 人工智能 计算机视觉
一、模块概述OpenCV的ML模块提供了丰富的机器学习算法,可用于解决各种计算机视觉和数据分析问题。本指南将详细介绍该模块中主要的机器学习算法,包括支持向量机(SVM)、K均值聚类(K-Means)和神经网络(ANN),并结合图像分类和聚类分析这两个典型应用场景进行代码实现与解释。二、主要函数及类详解(一)支持向量机(SVM):cv.ml.SVM_create()功能支持向量机(SVM)是一种强大
JavaScript的函数拦截技术详解
天天进步2015
前端开发 javascript 开发语言 ecmascript
引言在JavaScript的世界里,函数是一等公民。它们可以被赋值给变量,作为参数传递,甚至可以被动态修改。函数拦截(FunctionInterception)是一种强大的技术,允许开发者在不修改原始函数代码的情况下,拦截、监控和修改函数的行为。本文将深入探讨JavaScript函数拦截的各种技术、应用场景以及最佳实践。什么是函数拦截?函数拦截是指在函数执行前、执行中或执行后插入自定义逻辑的过程。
【MySQL基础-10】MySQL中的LENGTH()函数:用法详解与实例分析
AllenBright
# MySQL mysql 数据库
在MySQL数据库中,LENGTH()函数是一个非常常用的字符串函数,用于计算字符串的字节长度。理解并掌握LENGTH()函数的用法,对于处理字符串数据、优化查询以及进行数据验证都非常有帮助。本文将详细介绍LENGTH()函数的用法,并通过实例演示其在实际中的应用。1.LENGTH()函数的基本语法LENGTH()函数的基本语法如下:LENGTH(str)str:要计算长度的字符串或字段。可以是字
Linux进程间通信:消息队列与msgget函数使用详解
无形小手
本文还有配套的精品资源,点击获取简介:本文深入介绍了Linux消息队列的创建和操作方法,包括msgget()、msgsnd()和msgrcv()三个核心函数。介绍了通过消息队列实现进程间通信的基础实验步骤和关键要点,如键值计算、消息发送和接收,以及进程间通信时常见的权限控制、消息顺序、类型匹配和同步问题。通过学习这些内容,开发者能够更好地理解和掌握如何在项目中实现高效的进程间通信。1.Linux消
【区块链】跨链技术详解
还没入门的大菜狗
区块链
跨链技术详解:打通区块链孤岛一、跨链技术概述1.定义与必要性跨链技术是指实现不同区块链网络之间价值和信息互操作的解决方案。随着区块链生态系统的扩张,解决"区块链孤岛"问题变得至关重要。跨链技术解决的核心问题:不同区块链间的资产流动跨链数据和状态共享多链智能合约调用统一的用户体验2.跨链技术的基本挑战一致性保障:确保跨链交易的原子性验证复杂性:如何在一条链上验证另一条链的状态安全保证:防止双花攻击和
Linux信号处理详解:从基本概念到高级应用
chian-ocean
Linux linux 信号处理 运维
个人主页:chian-ocean文章专栏-Linux前言:在Linux系统中,信号(Signal)是操作系统用来通知进程发生某些事件的一种机制。信号是一种软件中断机制,可以被进程用来响应特定的事件,如终止进程、暂停进程、重新加载配置等。信号机制是Unix及其衍生系统的核心功能之一什么是信号生活中的信号也可以理解为一种通过特定方式传递信息、指令或警告的方式。在日常生活中,信号无处不在,帮助我们理解周
MySQL 的多版本并发控制
潇湘馆记
mysql 数据库
MySQL的多版本并发控制(MVCC)详解1.什么是MVCC?MVCC(Multi-VersionConcurrencyControl,多版本并发控制)是MySQLInnoDB引擎的一种并发控制机制,通过保存数据的多个版本,允许不同事务读取不同的数据版本,从而减少锁冲突,提高并发性能。2.MVCC主要用于哪种隔离级别?支持REPEATABLEREAD(可重复读)和READCOMMITTED(读已提
spring的自动配置原理
LCY133
spring后端 spring
Spring自动配置(Auto-Configuration)原理详解SpringBoot的自动配置是其核心特性之一,旨在根据应用的依赖和配置环境,自动完成Bean的创建与配置,减少开发者的手动配置工作。其核心思想是“约定优于配置”,通过智能化的默认行为简化开发流程。1.自动配置的核心机制a.条件化配置(Conditional)SpringBoot通过@Conditional系列注解判断是否满足条件
Spring Boot 中的 @ConditionalOnBean 注解详解
weixin_44563169
spring boot java 后端
SpringBoot中的@ConditionalOnBean注解详解1.前言2.`@ConditionalOnBean`作用与基本用法2.1`@ConditionalOnBean`的作用2.2基本用法示例:当`DataSource`Bean存在时,才创建`MyService`Bean3.`@ConditionalOnBean`详解3.1`value`和`type`属性(指定Bean类型)3.2`n
基于偏移量、游标分页的详解
B_rownJay
数据库 oracle
前言大量的数据集往往会被分成多个空间去存储。例如一本书就会有几十页几百页,因为把一本书都放在一页去展示不管是对生产者还是消费者都是及其不友好的。又比如在网页中我们常常会看到一页一页的数据,当然我们自己开发的时候也少不了做分页展示的需求。基于偏移量进行分页对于分页我们相较于使用游标进行分页更熟悉、见得更多的是基于偏移量进行分页。例如这样一个Get请求:brownjay.com/api/v1/book
Flink Cdc TiDB详解
24k小善
flink 大数据 java
1.什么是FlinkTiDBCDC?简单说就是用Flink实时抓取TiDB数据库的数据变化(比如新增、修改、删除),并将这些变化数据以流的形式处理,用于实时分析、同步到其他系统等场景。TiDB本身是分布式数据库,而Flink是流处理引擎,两者的结合适合需要高吞吐、低延迟的大规模数据处理场景[7][8]。2.底层原理TiDB侧:通过TiCDC组件(TiDB的变更数据捕获工具)捕获数据变更,类似MyS
C语言【文件操作】详解下
Run_Teenage
C语言基础 c语言
引言详细介绍了文件的随机读写函数和文件读取结束的判定看这篇博文前,希望您先仔细看一下这篇博文,理解一下文件指针和流的概念:C语言【文件操作】详解上-CSDN博客一、文件的随机读写函数1.fseek函数根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)。函数原型:intfseek(FILE*stream,longintoffset,intorigin);作用:重新定位流位置指示器参数:str
一切皆是映射:实现神经网络的硬件加速技术:GPU、ASIC(专用集成电路)和FPGA(现场可编程门阵列)
AI天才研究院
AI大模型企业级应用开发实战 DeepSeek R1 & 大数据AI人工智能大模型 计算科学 神经计算 深度学习 神经网络 大数据 人工智能 大型语言模型 AI AGI LLM Java Python 架构设计 Agent RPA
文章目录一切皆是映射:实现神经网络的硬件加速技术:GPU、ASIC(专用集成电路)和FPGA(现场可编程门阵列)1.背景介绍2.核心概念与联系3.核心算法原理&具体操作步骤3.1算法原理概述3.2算法步骤详解3.2.1GPU加速3.2.2ASIC加速3.2.3FPGA加速3.3算法优缺点GPUASICFPGA3.4算法应用领域4.数学模型和公式&详细讲解&举例说明4.1数学模型构建4.2公式推导过
平衡二叉树(AVL树):数据结构特性与自平衡技术详解
One Key Variable
课程设计
摘要平衡二叉树,尤其是AVL树,在追求高效数据存储与检索的场景中占据重要地位。本文深入剖析AVL树的数据结构特性,详细解读其自平衡技术原理与实现,帮助读者理解AVL树如何在动态数据操作中维持高效性能。一、引言在数据处理过程中,二叉搜索树虽能实现快速查找,但在频繁插入和删除节点时,可能因结构失衡导致查找效率大幅下降。AVL树作为一种自平衡二叉搜索树,通过严格的平衡条件和自平衡技术,确保树在动态操作下
Vue2与Vue3组件开发全维度对比实战指南
Forever丿顾北
专题文章 vue.js 前端 前端框架
Vue2与Vue3组件开发全维度对比实战指南一、组件基础架构对比1.1组件定义方式演进Vue2OptionsAPI详解在Vue2中,组件主要通过OptionsAPI来定义。OptionsAPI将组件的不同方面,如数据、方法、生命周期钩子等,分开定义在一个对象中。这种方式对于初学者来说,易于理解和上手。以一个简单的计数器组件为例:{{count}}增加exportdefault{data(){ret
Retrofit使用详解
烈焰晴天
Android
综述retrofit是由square公司开发的。square在github上发布了很多优秀的Android开源项目。例如:otto(事件总线),leakcanary(排查内存泄露),android-times-square(日历控件),dagger(依赖注入),picasso(异步加载图片),okhttp(网络请求),retrofit(网络请求)等等。更
C++中map和set的详解
程序员Hagei
c++ 算法 开发语言
C++中map和set的介绍与使用在C++编程中,map和set是标准模板库(STL)中两种非常重要的关联容器。它们基于平衡二叉搜索树(通常是红黑树)的数据结构来实现,提供了高效的数据存储和检索功能。本文将详细介绍map和set的特点、用法以及一些常见的操作示例。一、map的介绍与使用1.map的基本概念map是一个键值对容器,其中每个键都是唯一的,且按照升序排序。map的内部结构是红黑树,这使得
解线性方程组
qiuwanchi
package gaodai.matrix;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Sc
在mysql内部存储代码
annan211
性能 mysql 存储过程 触发器
在mysql内部存储代码
在mysql内部存储代码,既有优点也有缺点,而且有人倡导有人反对。
先看优点:
1 她在服务器内部执行,离数据最近,另外在服务器上执行还可以节省带宽和网络延迟。
2 这是一种代码重用。可以方便的统一业务规则,保证某些行为的一致性,所以也可以提供一定的安全性。
3 可以简化代码的维护和版本更新。
4 可以帮助提升安全,比如提供更细
Android使用Asynchronous Http Client完成登录保存cookie的问题
hotsunshine
android
Asynchronous Http Client是android中非常好的异步请求工具
除了异步之外还有很多封装比如json的处理,cookie的处理
引用
Persistent Cookie Storage with PersistentCookieStore
This library also includes a PersistentCookieStore whi
java面试题
Array_06
java 面试
java面试题
第一,谈谈final, finally, finalize的区别。
final-修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能
网站加速
oloz
网站加速
前序:本人菜鸟,此文研究总结来源于互联网上的资料,大牛请勿喷!本人虚心学习,多指教.
1、减小网页体积的大小,尽量采用div+css模式,尽量避免复杂的页面结构,能简约就简约。
2、采用Gzip对网页进行压缩;
GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNⅨ系统的文件压缩。我们在Linux中经常会用到后缀为.gz
正确书写单例模式
随意而生
java 设计模式 单例
单例模式算是设计模式中最容易理解,也是最容易手写代码的模式了吧。但是其中的坑却不少,所以也常作为面试题来考。本文主要对几种单例写法的整理,并分析其优缺点。很多都是一些老生常谈的问题,但如果你不知道如何创建一个线程安全的单例,不知道什么是双检锁,那这篇文章可能会帮助到你。
懒汉式,线程不安全
当被问到要实现一个单例模式时,很多人的第一反应是写出如下的代码,包括教科书上也是这样
单例模式
香水浓
java
懒汉 调用getInstance方法时实例化
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(null == ins
安装Apache问题:系统找不到指定的文件 No installed service named "Apache2"
AdyZhang
apache http server
安装Apache问题:系统找不到指定的文件 No installed service named "Apache2"
每次到这一步都很小心防它的端口冲突问题,结果,特意留出来的80端口就是不能用,烦。
解决方法确保几处:
1、停止IIS启动
2、把端口80改成其它 (譬如90,800,,,什么数字都好)
3、防火墙(关掉试试)
在运行处输入 cmd 回车,转到apa
如何在android 文件选择器中选择多个图片或者视频?
aijuans
android
我的android app有这样的需求,在进行照片和视频上传的时候,需要一次性的从照片/视频库选择多条进行上传
但是android原生态的sdk中,只能一个一个的进行选择和上传。
我想知道是否有其他的android上传库可以解决这个问题,提供一个多选的功能,可以使checkbox之类的,一次选择多个 处理方法
官方的图片选择器(但是不支持所有版本的androi,只支持API Level
mysql中查询生日提醒的日期相关的sql
baalwolf
mysql
SELECT sysid,user_name,birthday,listid,userhead_50,CONCAT(YEAR(CURDATE()),DATE_FORMAT(birthday,'-%m-%d')),CURDATE(), dayofyear( CONCAT(YEAR(CURDATE()),DATE_FORMAT(birthday,'-%m-%d')))-dayofyear(
MongoDB索引文件破坏后导致查询错误的问题
BigBird2012
mongodb
问题描述:
MongoDB在非正常情况下关闭时,可能会导致索引文件破坏,造成数据在更新时没有反映到索引上。
解决方案:
使用脚本,重建MongoDB所有表的索引。
var names = db.getCollectionNames();
for( var i in names ){
var name = names[i];
print(name);
Javascript Promise
bijian1013
JavaScript Promise
Parse JavaScript SDK现在提供了支持大多数异步方法的兼容jquery的Promises模式,那么这意味着什么呢,读完下文你就了解了。
一.认识Promises
“Promises”代表着在javascript程序里下一个伟大的范式,但是理解他们为什么如此伟大不是件简
[Zookeeper学习笔记九]Zookeeper源代码分析之Zookeeper构造过程
bit1129
zookeeper
Zookeeper重载了几个构造函数,其中构造者可以提供参数最多,可定制性最多的构造函数是
public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd, boolea
【Java命令三】jstack
bit1129
jstack
jstack是用于获得当前运行的Java程序所有的线程的运行情况(thread dump),不同于jmap用于获得memory dump
[hadoop@hadoop sbin]$ jstack
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F
jboss 5.1启停脚本 动静分离部署
ronin47
以前启动jboss,往各种xml配置文件,现只要运行一句脚本即可。start nohup sh /**/run.sh -c servicename -b ip -g clustername -u broatcast jboss.messaging.ServerPeerID=int -Djboss.service.binding.set=p
UI之如何打磨设计能力?
brotherlamp
UI ui教程 ui自学 ui资料 ui视频
在越来越拥挤的初创企业世界里,视觉设计的重要性往往可以与杀手级用户体验比肩。在许多情况下,尤其对于 Web 初创企业而言,这两者都是不可或缺的。前不久我们在《右脑革命:别学编程了,学艺术吧》中也曾发出过重视设计的呼吁。如何才能提高初创企业的设计能力呢?以下是 9 位创始人的体会。
1.找到自己的方式
如果你是设计师,要想提高技能可以去设计博客和展示好设计的网站如D-lists或
三色旗算法
bylijinnan
java 算法
import java.util.Arrays;
/**
问题:
假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,
您希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳
子上进行这个动作,而且一次只能调换两个旗子。
网上的解法大多类似:
在一条绳子上移动,在程式中也就意味只能使用一个阵列,而不使用其它的阵列来
警告:No configuration found for the specified action: \'s
chiangfai
configuration
1.index.jsp页面form标签未指定namespace属性。
<!--index.jsp代码-->
<%@taglib prefix="s" uri="/struts-tags"%>
...
<s:form action="submit" method="post"&g
redis -- hash_max_zipmap_entries设置过大有问题
chenchao051
redis hash
使用redis时为了使用hash追求更高的内存使用率,我们一般都用hash结构,并且有时候会把hash_max_zipmap_entries这个值设置的很大,很多资料也推荐设置到1000,默认设置为了512,但是这里有个坑
#define ZIPMAP_BIGLEN 254
#define ZIPMAP_END 255
/* Return th
select into outfile access deny问题
daizj
mysql txt 导出数据到文件
本文转自:http://hatemysql.com/2010/06/29/select-into-outfile-access-deny%E9%97%AE%E9%A2%98/
为应用建立了rnd的帐号,专门为他们查询线上数据库用的,当然,只有他们上了生产网络以后才能连上数据库,安全方面我们还是很注意的,呵呵。
授权的语句如下:
grant select on armory.* to rn
phpexcel导出excel表简单入门示例
dcj3sjt126com
PHP Excel phpexcel
<?php
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
if (PHP_SAPI == 'cli')
die('This example should only be run from a Web Brows
美国电影超短200句
dcj3sjt126com
电影
1. I see. 我明白了。2. I quit! 我不干了!3. Let go! 放手!4. Me too. 我也是。5. My god! 天哪!6. No way! 不行!7. Come on. 来吧(赶快)8. Hold on. 等一等。9. I agree。 我同意。10. Not bad. 还不错。11. Not yet. 还没。12. See you. 再见。13. Shut up!
Java访问远程服务
dyy_gusi
httpclient webservice get post
随着webService的崛起,我们开始中会越来越多的使用到访问远程webService服务。当然对于不同的webService框架一般都有自己的client包供使用,但是如果使用webService框架自己的client包,那么必然需要在自己的代码中引入它的包,如果同时调运了多个不同框架的webService,那么就需要同时引入多个不同的clien
Maven的settings.xml配置
geeksun
settings.xml
settings.xml是Maven的配置文件,下面解释一下其中的配置含义:
settings.xml存在于两个地方:
1.安装的地方:$M2_HOME/conf/settings.xml
2.用户的目录:${user.home}/.m2/settings.xml
前者又被叫做全局配置,后者被称为用户配置。如果两者都存在,它们的内容将被合并,并且用户范围的settings.xml优先。
ubuntu的init与系统服务设置
hongtoushizi
ubuntu
转载自:
http://iysm.net/?p=178 init
Init是位于/sbin/init的一个程序,它是在linux下,在系统启动过程中,初始化所有的设备驱动程序和数据结构等之后,由内核启动的一个用户级程序,并由此init程序进而完成系统的启动过程。
ubuntu与传统的linux略有不同,使用upstart完成系统的启动,但表面上仍维持init程序的形式。
运行
跟我学Nginx+Lua开发目录贴
jinnianshilongnian
nginx lua
使用Nginx+Lua开发近一年的时间,学习和实践了一些Nginx+Lua开发的架构,为了让更多人使用Nginx+Lua架构开发,利用春节期间总结了一份基本的学习教程,希望对大家有用。也欢迎谈探讨学习一些经验。
目录
第一章 安装Nginx+Lua开发环境
第二章 Nginx+Lua开发入门
第三章 Redis/SSDB+Twemproxy安装与使用
第四章 L
php位运算符注意事项
home198979
位运算 PHP &
$a = $b = $c = 0;
$a & $b = 1;
$b | $c = 1
问a,b,c最终为多少?
当看到这题时,我犯了一个低级错误,误 以为位运算符会改变变量的值。所以得出结果是1 1 0
但是位运算符是不会改变变量的值的,例如:
$a=1;$b=2;
$a&$b;
这样a,b的值不会有任何改变
Linux shell数组建立和使用技巧
pda158
linux
1.数组定义 [chengmo@centos5 ~]$ a=(1 2 3 4 5) [chengmo@centos5 ~]$ echo $a 1 一对括号表示是数组,数组元素用“空格”符号分割开。
2.数组读取与赋值 得到长度: [chengmo@centos5 ~]$ echo ${#a[@]} 5 用${#数组名[@或
hotspot源码(JDK7)
ol_beta
java HotSpot jvm
源码结构图,方便理解:
├─agent Serviceab
Oracle基本事务和ForAll执行批量DML练习
vipbooks
oracle sql
基本事务的使用:
从账户一的余额中转100到账户二的余额中去,如果账户二不存在或账户一中的余额不足100则整笔交易回滚
select * from account;
-- 创建一张账户表
create table account(
-- 账户ID
id number(3) not null,
-- 账户名称
nam