selenium and auto

selenium(Java)WebDriverWait等待机制

       //标题是不是“百度一下,你就知道”
18 new WebDriverWait(driver,5).until(ExpectedConditions.titleIs("百度一下,你就知道"));
19 //标题是不是包含“百度一下”
20 new WebDriverWait(driver,5).until(ExpectedConditions.titleContains("百度一下"));
21 //判断该元素是否被加载在DOM中,并不代表该元素一定可见
22 new WebDriverWait(driver,5).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id='kw']")));
23 //判断元素(定位后)是否可见
24 new WebDriverWait(driver,5).until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//*[@id='kw']"))));
25 //判断元素是否可见(非隐藏,并且元素的宽和高都不等以0)
26 new WebDriverWait(driver,5).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='kw']")));
27 //只要存在一个就是true
28 ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath("//*[@id='kw']"));
29 //元素中的text是否包含参数中的的字符串(元素要存在,否则会抛NoSuch异常)
30 ExpectedConditions.textToBePresentInElementLocated(By.xpath("//*[@id='kw']"), "百度一下");
31 //元素的value属性中是否包含参数中的字符串
32 ExpectedConditions.textToBePresentInElementValue(By.xpath("//*[@id='kw']"), "***");
33 //判断该表单是否可以切过去,可以就切过去并返回true,否则放回false
34 ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("**"));
35 //判断某个元素是否不存在于DOM或不可见
36 ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='kw']"));
37 //判断元素是否可以点击
38 ExpectedConditions.elementToBeClickable(By.xpath("//*[@id='kw']"));
39 //等到一个元素从DOM中移除
40 ExpectedConditions.stalenessOf(driver.findElement(By.xpath("//*[@id='kw']")));
41 //判断某个元素是否被选中,一般用在下拉列表
42 ExpectedConditions.elementToBeSelected(By.xpath("//*[@id='kw']"));
43 //判断某个元素的选中状态是否符合预期
44 ExpectedConditions.elementSelectionStateToBe(By.xpath("//*[@id='kw']"), true);
45 //判断某个元素(已定位)的选中状态是否符合预期
46 ExpectedConditions.elementSelectionStateToBe(driver.findElement(By.xpath("//*[@id='kw']")), false);
47 //判断页面中是否存在alert
48 new WebDriverWait(driver,5).until(ExpectedConditions.alertIsPresent());


Web自动化常用方法封装(不定时更新)


/**
* JScript实现鼠标悬停
*/
public void mouseHoverJScript(By by,WebElement HoverElement) {
// TODO Auto-generated method stub
try {
if (isElementPresent(by)) { //isElementPresent() :自己封装的判断元素是否存在的方法
String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}";
((JavascriptExecutor) driver).executeScript(mouseOverScript, HoverElement);
} else {
System.out.println("Element was not visible to hover " + "\n");
}
} catch (StaleElementReferenceException e) {
// TODO: handle exception
System.out.println("Element with " + HoverElement + "元素未附加到页面文档" + Arrays.toString(e.getStackTrace()));
} catch (NoSuchElementException e) {
// TODO: handle exception
System.out.println("Element " + HoverElement + " 元素未在DOM中没有找到" + Arrays.toString(e.getStackTrace()));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
System.out.println("悬停时发生错误" + Arrays.toString(e.getStackTrace()));
}
}

/**
* 等待弹窗出现并点掉
*/
public void waitAlertClick(){
WebDriverWait wait = new WebDriverWait(driver, 15);
try {
Alert alert = wait.until(new ExpectedCondition<Alert>() {
@Override
public Alert apply(WebDriver driver1) {
try {
return driver.switchTo().alert();
} catch (NoAlertPresentException | UnhandledAlertException ignored) {
return null;
}
}
});
alert.accept();
} catch (NullPointerException e) {
System.out.println("-----------------------No Alert-----------------------");
}
}

/**
*
*获取弹窗,便于进行对其进行操作
* @return
*/
public Alert getAlert(){
WebDriverWait wait = new WebDriverWait(driver, 15);
Alert alert;
try{
alert= wait.until(new ExpectedCondition<Alert>() {
@Override
public Alert apply(WebDriver driver1) {
try {
return driver.switchTo().alert();
} catch (NoAlertPresentException | UnhandledAlertException ignored) {
return null;
}
}
});
}catch (TimeoutException ignored){
System.out.println("-----------------------Time Out:No Alert-----------------------");
return null;
}
return alert;
}

/**
* 等待元素存在并可见
* @param by
* isEnable用于存储input、select等元素的可编辑状态,可以编辑返回true,否则返回false
*/
public void waitEleIsDisplay(By by){
WebDriverWait wait = new WebDriverWait(driver, 20);
try {
wait.until(new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver1) {
try {
WebElement ele=driver.findElement(by);
return ele.isDisplayed()&&ele.isEnabled();
}catch (NoSuchElementException e){
return null;
}
}
});
}catch (TimeoutException e ){
System.out.println("------------Timed out after 20 seconds waiting for:"+by+"------------");
}

}


/**
* 发送字符串到文本框或者其他<br>
* 如果普通的element.sendKeys无法使用,请尝试使用此方法
* @param element
* @param keys
*/
public void mouseSendKeys(WebElement element, String keys) {
Actions action = new Actions(driver);
action.moveToElement(element);
action.click();
action.sendKeys(keys);
action.perform();
}
 

/**
* 截图-当前页面
* @param driver
* @return booelan 截图是否成功
*/
public boolean screenshot() {
String pngName = String.valueOf(System.currentTimeMillis())+".png";
String capturePath = DcitsUtil.SCREENSHOT_PATH + "/" + pngName; //DcitsUtil.SCREENSHOT_PATH 为封装的路径
File screenShotFile = ((TakesScreenshot)this.driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(screenShotFile, new File(capturePath));
} catch (Exception e) {
// TODO: handle exception
System.out.println(""截图出错+e.getMessage())
return false;
}
return true;
}
 

selenium+Java,xpath定位方法详解(搬运留存)

用xpath绝对路径比较费事费力,还容易报错,下面几种模糊定位比较灵活好用

 driver.findElement(By.xpath("//*[@id='J_login_form']/dl/dt/input[@id='J_password']"));

其中//*[@id=’ J_login_form’]这一段是指在根元素下查找任意id为J_login_form的元素,此时相当于引用到了form元素。后面的路径必须按照源码的层级依次往下写。我们要找的input元素包含在一个dt标签内,而dt又包含在dl标签内,所以中间必须写上dl和dt两层,才到input这层。当然我们也可以用*号省略具体的标签名称,但元素的层级关系必须体现出来,比如我们不能写成//*[@id='J_login_form']/input[@id='J_password'],这样肯定会报错的。

另外一种写法:driver.findElement(By.xpath("//*[@id='J_login_form']/*/*/input[@id='J_password']"));

 

a. 用contains关键字,定位代码如下:

driver.findElement(By.xpath(“//a[contains(@href, ‘logout’)]”));

这句话的意思是寻找页面中href属性值包含有logout这个单词的所有a元素,由于这个退出按钮的href属性里肯定会包含logout,所以这种方式是可行的,也会经常用到。其中@后面可以跟该元素任意的属性名。

b. 用start-with,定位代码如下:

driver.findElement(By.xpath(“//a[starts-with(@rel, ‘nofo’)]));

这种方式一般用于知道超链接上显示的部分或全部文本信息时,可以使用。

这句的意思是寻找rel属性以nofo开头的a元素。其中@后面的rel可以替换成元素的任意其他属性

c. 用Text关键字,定位代码如下:

driver.findElement(By.xpath(“//a[contains(text(), ’退出’)]));

直接查找页面当中所有的退出二字,根本就不用知道它是个a元素了。这种方法也经常用于纯文字的查找

d.如果知道超链接元素的文本内容,也可以用

driver.findElement(By.xpath(“//a[contains(text(), ’退出’)]));

3.XPath 关于网页中的动态属性的定位,例如,ASP.NET 应用程序中动态生成 id 属性值,可以有以下四种方法:

a.starts-with    例子: input[starts-with(@id,'ctrl')]        解析:匹配以 ctrl开始的属性值

b.ends-with     例子:input[ends-with(@id,'_userName')]    解析:匹配以 userName 结尾的属性值

c.contains()     例子:Input[contains(@id,'userName')]     解析:匹配含有 userName 属性值

 

 

selenium+chromedriver在服务器运行

转自:https://zm.sm-tc.cn/?src=l4uLj4zF0NCdk5CY0ZyMm5HRkZqL0JmakZiSksrNztCejYuWnJOa0Juai56Wk4zQyMbJyc7IyM4%3D&from=derive&depth=8&link_type=60&wap=false&force=true&bu=news_natural&v=1&uid=8aad8df7911f11ad96b3e7defcf58fe0&restype=1

1.前言

想使用selenium从网站上抓数据,但有时候使用phantomjs会出错。chrome现在也有无界面运行模式了,以后就可以不用phantomjs了。

但在服务器安装chrome时出现了一些错误,这里总结一下整个安装过程

2.ubuntu上安装chrome

# Install Google Chrome
# https://askubuntu.com/questions/79280/how-to-install-chrome-browser-properly-via-command-line
sudo apt-get install libxss1 libappindicator1 libindicator7
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.debsudo dpkg -i google-chrome*.deb # Might show "errors", fixed by next line sudo apt-get install -f

这时应该已经安装好了,用下边的命行运行测试一下:

google-chrome --headless --remote-debugging-port=9222 https://chromium.org --disable-gpu

这里是使用headless模式进行远程调试,ubuntu上大多没有gpu,所以–disable-gpu以免报错。
之后可以再打开一个ssh连接到服务器,使用命令行访问服务器的本地的9222端口:

curl http://localhost:9222

如果安装好了,会看到调试信息。但我这里会报一个错误,下边是错误的解决办法。

1)可能的错误解决方法

运行完上边的命令可能会报一个不能在root下运行chrome的错误。这个时候使用下边方设置一下chrome

1.找到google-chrome文件
我的位置位于/opt/google/chrome/
2.用vi打开google-chrome文件

vi /opt/google/chrome/google-chrome

在文件中找到

exec -a "$0" "$HERE/chrome" "$@"

3.在后面添加 –user-data-dir –no-sandbox即可,整条shell命令就是

exec -a "$0" "$HERE/chrome" "$@" --user-data-dir --no-sandbox

4.再重新打开google-chrome即可正常访问!

3.安装chrome驱动chromedriver

下载chromedriver
chromedriver提供了操作chrome的api,是selenium控制chrome的桥梁。

chromedriver最好安装最新版的,记的我一开始安装的不是最新版的,会报一个错。用最新版的chromedriver就没有问题,最新版的可以在下边地址找到
https://sites.google.com/a/chromium.org/chromedriver/downloads

我写这个文章时最新版是2.37

wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip
unzip chromedriver_linux64.zip

到这里服务器端的无界面版chrome就安装好了。

4.无界面版chrome使用方法

from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument("user-agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'")
wd = webdriver.Chrome(chrome_options=chrome_options,executable_path='/home/chrome/chromedriver')
wd.get("https://www.163.com")
content = wd.page_source.encode('utf-8')print content
wd.quit()

这里chrome_options中的第三项设置参数,使用这个设置可以避免网站检测到你使用的是无界模式进行反抓取。

下边另外的两项设置,不进行设置时在桌面版linux系统,或者mac系统上会打开有界面的chrome.调试时可以注释掉下边两行使用有界面版chrome来调试程序。

chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')

5.参考

https://jiayi.space/post/zai-ubuntufu-wu-qi-shang-shi-yong-chrome-headless
https://blog.csdn.net/u013703963/article/details/71083802

 

 

每次当selenium启动chrome浏览器的时候,chrome浏览器很干净,没有插件、没有收藏、没有历史记录,这是因为selenium在启动chrome时为了保证最快的运行效率,启动了一个裸浏览器,这就是为什么需要配置参数的原因,但是有些时候我们需要的不仅是一个裸浏览器。

selenium启动配置参数接收是ChromeOptions类,创建方式如下:

from selenium import webdriver

option = webdriver.ChromeOptions()

创建了ChromeOptions类之后就是添加参数,添加参数有几个特定的方法,分别对应添加不同类型的配置项目。

设置 chrome 二进制文件位置 (binary_location)

from selenium import webdriver

option = webdriver.ChromeOptions()

# 添加启动参数

option.add_argument()

# 添加扩展应用

option.add_extension()

option.add_encoded_extension()

# 添加实验性质的设置参数

option.add_experimental_option()

# 设置调试器地址

option.debugger_address()

常用配置参数:

from selenium import webdriver

option = webdriver.ChromeOptions()

# 添加UA

options.add_argument('user-agent="MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"')

# 指定浏览器分辨率

options.add_argument('window-size=1920x3000')

# 谷歌文档提到需要加上这个属性来规避bug

chrome_options.add_argument('--disable-gpu')

 # 隐藏滚动条, 应对一些特殊页面

options.add_argument('--hide-scrollbars')

# 不加载图片, 提升速度

options.add_argument('blink-settings=imagesEnabled=false')

# 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败

options.add_argument('--headless')

# 以最高权限运行

options.add_argument('--no-sandbox')

# 手动指定使用的浏览器位置

options.binary_location = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"

#添加crx插件

option.add_extension('d:\crx\AdBlock_v2.17.crx')

# 禁用JavaScript

option.add_argument("--disable-javascript")

# 设置开发者模式启动,该模式下webdriver属性为正常值

options.add_experimental_option('excludeSwitches', ['enable-automation'])

# 禁用浏览器弹窗

prefs = {  

    'profile.default_content_setting_values' :  {  

        'notifications' : 2  

     }  

}  

options.add_experimental_option('prefs',prefs)

driver=webdriver.Chrome(chrome_options=chrome_options)

浏览器地址栏参数:

在浏览器地址栏输入下列命令得到相应的信息

about:version - 显示当前版本

  about:memory - 显示本机浏览器内存使用状况

  about:plugins - 显示已安装插件

  about:histograms - 显示历史记录

  about:dns - 显示DNS状态

  about:cache - 显示缓存页面

  about:gpu -是否有硬件加速

  chrome://extensions/ - 查看已经安装的扩展
image

其他配置项目参数

–user-data-dir=”[PATH]”

# 指定用户文件夹User Data路径,可以把书签这样的用户数据保存在系统分区以外的分区

  –disk-cache-dir=”[PATH]“

# 指定缓存Cache路径

  –disk-cache-size=

# 指定Cache大小,单位Byte

  –first run

# 重置到初始状态,第一次运行

  –incognito

# 隐身模式启动

  –disable-javascript

# 禁用Javascript

  --omnibox-popup-count="num"

# 将地址栏弹出的提示菜单数量改为num个

  --user-agent="xxxxxxxx"

# 修改HTTP请求头部的Agent字符串,可以通过about:version页面查看修改效果

  --disable-plugins

# 禁止加载所有插件,可以增加速度。可以通过about:plugins页面查看效果

  --disable-javascript

# 禁用JavaScript,如果觉得速度慢在加上这个

  --disable-java

# 禁用java

  --start-maximized

# 启动就最大化

  --no-sandbox

# 取消沙盒模式

  --single-process

# 单进程运行

  --process-per-tab

# 每个标签使用单独进程

  --process-per-site

# 每个站点使用单独进程

  --in-process-plugins

# 插件不启用单独进程

  --disable-popup-blocking

# 禁用弹出拦截

  --disable-plugins

# 禁用插件

  --disable-images

# 禁用图像

  --incognito

# 启动进入隐身模式

  --enable-udd-profiles

# 启用账户切换菜单

  --proxy-pac-url

# 使用pac代理 [via 1/2]

  --lang=zh-CN

# 设置语言为简体中文

  --disk-cache-dir

# 自定义缓存目录

  --disk-cache-size

# 自定义缓存最大值(单位byte)

  --media-cache-size

# 自定义多媒体缓存最大值(单位byte)

  --bookmark-menu

# 在工具 栏增加一个书签按钮

  --enable-sync

# 启用书签同步

 

 

1.输入内容

  • send_keys('valve'):输入内容valve
#定位输入框
input_box = browser.find_element_by_id('kw')
try:
    #输入内容:selenium
    input_box.send_keys('selenium')
    print('搜索关键词:selenium')
except Exception as e:
    print('fail')

#输出内容:搜索关键词:selenium

2.点击按钮

  • click():点击按钮
#定位搜索按钮
button = browser.find_element_by_id('su')
try:
    #点击搜索按钮
    button.click()
    print('成功搜索')
except Exception as e:
    print('fail搜索')
#输出内容:成功搜索

3.清空输入框

  • clear():清空输入框
#clear():清空输入框
try:
    input_box.clear()
    print('成功清空输入框')
except Exception as e:
    print('fail清空输入框')
#输出内容:成功清空输入框

4.输入内容、点击按钮、清空输入完整实例

from selenium import webdriver
import time  

browser = webdriver.Chrome()
browser.maximize_window()   #设置浏览器大小:全屏
browser.get('https://www.baidu.com')  

#定位输入框
input_box = browser.find_element_by_id('kw')
try:
    #输入内容:selenium
    input_box.send_keys('selenium')
    print('搜索关键词:selenium')
except Exception as e:
    print('fail')
#输出内容:搜索关键词:selenium

#定位搜索按钮
button = browser.find_element_by_id('su')
try:
    #点击搜索按钮
    button.click()
    print('成功搜索')
except Exception as e:
    print('fail搜索')
#输出内容:成功搜索

#clear():清空输入框
try:
    input_box.clear()
    print('成功清空输入框')
except Exception as e:
    print('fail清空输入框')
#输出内容:成功清空输入框

5.submit():模拟‘回车’操作

  • submit():通常应用于提交表单;例如:搜索框输入内容后的回车操作。
from selenium import webdriver
import time  

browser = webdriver.Chrome()
browser.maximize_window()   #设置浏览器大小:全屏
browser.get('https://www.baidu.com')  

#定位输入框
input_box = browser.find_element_by_id('kw')
#输入关键词:selenium
input_box.send_keys('selenium')
#模拟回车操作
try:
    input_box.submit()
    print('成功回车')
except Exception as e:
    print('fail')
#输出内容:成功回车

 

 有些元素调用clear()不能清除方法,网上大多数的方法都是发送ctrl +a 在发送delete,比较麻烦。下面介绍一种方法。

browser.find_element_by_class_name("element").send_keys(chr(127)*len(10))

127对应的是删除。
二进制     十进制     十六进制     缩写     可以显示的表示法     名称/意义
0000 0000     0     00     NUL     ␀     空字符(Null)
0000 0001     1     01     SOH     ␁     标题开始
0000 0010     2     02     STX     ␂     本文开始
0000 0011     3     03     ETX     ␃     本文结束
0000 0100     4     04     EOT     ␄     传输结束
0000 0101     5     05     ENQ     ␅     请求
0000 0110     6     06     ACK     ␆     确认回应
0000 0111     7     07     BEL     ␇     响铃
0000 1000     8     08     BS     ␈     退格
0000 1001     9     09     HT     ␉     水平定位符号
0000 1010     10     0A     LF     ␊     换行键
0000 1011     11     0B     VT     ␋     垂直定位符号
0000 1100     12     0C     FF     ␌     换页键
0000 1101     13     0D     CR     ␍     归位键
0000 1110     14     0E     SO     ␎     取消变换(Shift out)
0000 1111     15     0F     SI     ␏     启用变换(Shift in)
0001 0000     16     10     DLE     ␐     跳出数据通讯
0001 0001     17     11     DC1     ␑     设备控制一(XON 启用软件速度控制)
0001 0010     18     12     DC2     ␒     设备控制二
0001 0011     19     13     DC3     ␓     设备控制三(XOFF 停用软件速度控制)
0001 0100     20     14     DC4     ␔     设备控制四
0001 0101     21     15     NAK     ␕     确认失败回应
0001 0110     22     16     SYN     ␖     同步用暂停
0001 0111     23     17     ETB     ␗     区块传输结束
0001 1000     24     18     CAN     ␘     取消
0001 1001     25     19     EM     ␙     连接介质中断
0001 1010     26     1A     SUB     ␚     替换
0001 1011     27     1B     ESC     ␛     跳出
0001 1100     28     1C     FS     ␜     文件分割符
0001 1101     29     1D     GS     ␝     组群分隔符
0001 1110     30     1E     RS     ␞     记录分隔符
0001 1111     31     1F     US     ␟     单元分隔符
0111 1111     127     7F     DEL     ␡     删除
————————————————
版权声明:本文为CSDN博主「York1996」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/york1996/article/details/97312612

 

 

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium. webdriver.support.wait import WebDriverWait
browser = webdriver.Chrome()
#延时等待
wait = WebDriverWait(browser, 1)
BL = str(float((X).split('%')[0]) + 0.01)
#获取节点对象
Ratio = wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="root"]/div/div/div/div[1]/div[2]/div[4]/div/div/div[2]/div/div[1]/div[3]/div[2]/input')))
#双击事件
ActionChains(browser).double_click(Ratio).perform()
#输入内容
Ratio.send_keys(BL)

 


WebElement element = browser.getWebDriver().findElement(By.xpath("xpath"));
//点击
element.click();
//相当于ctrl+a 快捷键全选
element.sendKeys(Keys.chord(Keys.CONTROL, "a"));
//快捷键删除
element.sendKeys(Keys.DELETE);

 

#页面刷新
web.refresh()
#后退
web.back()
#前进
web.forward()
#窗口大小
web.set_window_size(540,960)
#窗口最大
web.maximize_window()
#截屏
web.get_sreenshot_as_file('1.jpg')

self.driver = Chrome(CHROME_DRIVER) #初始化对象
self.driver.set_window_size(1280, 1024) #设置窗口大小
self.driver.execute_script(
'localStorage.setItem("pre_appadmin_login_2541044284@qq.com",JSON.stringify(%s))' % self.local_storage)#设置localStorage本地缓存

self.driver.get_screenshot_as_file(os.path.join(BASE_DIR, 'yanzheng.png'))#获取当前窗口截屏并保存在程序文件根目录

image_position = self.driver.find_element_by_id('imgcaptcha')#获取验证码图片元素
left = image_position.location['x']#获取验证最左边位置
top = image_position.location['y']#获取验证码上边位置
right = left + image_position.size['width']#获取验证码右边位置
bottom = top + image_position.size['height']#获取验证码下边位置

open_img = Image.open('yanzheng.png')#打开屏幕截图
open_img = open_img.crop((left, top, right, bottom))#使用获取到的位置剪切图片
open_img.show()#显示图片
output = input('输入验证码结果:\n')

raw_cookies = 'BIDUPSID=ADE115AEB76A628B0FEDFBA2BEA2DC3F; PSTM=1573536348; BAIDUID=BFECE6CAB930BC30B24FC3DF42DFC0B0:FG=1; uc_login_unique=2f5b71b0251e795b1e39a2976623ebb4; uc_recom_mark=cmVjb21tYXJrXzUyNTQyMzE%3D; Hm_up_41fc030db57d5570dd22f78997dc4a7e=%7B%22uid_%22%3A%7B%22value%22%3A%225254231%22%2C%22scope%22%3A1%7D%7D; Hm_ct_41fc030db57d5570dd22f78997dc4a7e=306*1*5254231; BAIDUID_BFESS=B5D3BE945DA99101BD218F3020EEDB3F:FG=1; RT="z=1&dm=baidu.com&si=aue1xwc5wa&ss=khd54fii&sl=0&tt=0&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ul=1uh&hd=1ut"; TJSSID=gquiiriu7mtvqoopb9cmmelm13; Hm_lvt_41fc030db57d5570dd22f78997dc4a7e=1605433552,1605488263,1605488299,1605590129; SIGNIN_UC=70a2711cf1d3d9b1a82d2f87d633bd8a03556025811tV64pbgrg9zD7iQpLop%2BwXIs8ZpTFtUdOHarnkkIUa2WEGbin5%2FnuPAxVvd%2BE5JD4y72dxZ5pQK94ahVUJGEH5PdMbfleB8Epo%2BWLEaPVBf2R%2B8v2hgBmrxkB6p4oBBgxnF8Uyni1oDnttNkhXAnMKkPCTQAwsp6id0XZBITSgymUjK8%2BZWNp9g5OrdDH9IyxnF8Uyni1oDnttNkhXAnMKkPCTQAwsp6id0XZBITSgzVqGdQBOHDBkaMCM1Y9uVh3KrDeaYDP0jN9BkleHFOQMm4Jb%2BKOcMzhpbBLO%2FBba3QHwZf0zAG%2BF3TOmXiFL1U3NX3heqyDI6WCVZDy0jYUQ%3D%3D52309845942015840786124873273437; OPTYPE=u; __cas__st__=2cb34098b9eb6906055e7e034b80ff004d220123ca7f5ed8d5db0b2a1146193d356333d295198707f163ece5; __cas__id__=5254231; Hm_lpvt_41fc030db57d5570dd22f78997dc4a7e=1605590134'
def get_cookies(raw_cookies):
weipinhui_cookies_dict = {}
for lies in raw_cookies.split(';'):
key,word = lies.split('=',1)
weipinhui_cookies_dict[key] = word
return weipinhui_cookies_dict
set_cookies = get_cookies(raw_cookies)
# 删除到期密钥
for cookie in set_cookies:
if 'expiry' in cookie:
del cookie['expiry']
web.get_cookies()
web.delete_all_cookies()
# web.add_cookie(set_cookies)
# 定位方式
driver.find_element(s)_by_id
_class_name
_xpath
_link_text
_partial_link_text
_tag_name

 

鼠标事件

官方把它叫做“行为链”。ActionChains可以完成简单的交互行为,例如鼠标移动,鼠标点击事件,键盘输入,以及内容菜单交互。

click(on_element=None) ——单击鼠标左键

click_and_hold(on_element=None) ——点击鼠标左键,不松开

context_click(on_element=None) ——点击鼠标右键

double_click(on_element=None) ——双击鼠标左键

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(to_element) ——鼠标移动到某个元素

move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置

perform() ——执行链中的所有动作

release(on_element=None) ——在某个元素位置松开鼠标左键

send_keys(*keys_to_send) ——发送某个键到当前焦点的元素

send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素



深入了解可以参考 https://blog.csdn.net/huilan_same/article/details/52305176

move_to_element_with_offsetclick_and_hold会经常用到破解验证码中。

 

触摸操作 (TouchAction)

该事件仅仅针对移动端、触屏版

flick_element(on_element, xoffset, yoffset, speed) # 以元素为起点以一定速度向下滑动

scroll_from_element(on_element xoffset yoffset) #以元素为起点向下滑动

double_tap(on_element)                                     #双击   

flick_element(on_element, xoffset, yoffset, speed)         #从元素开始以指定的速度移动

long_press(on_element)                                            #长按不释放

move(xcoord, ycoord)                                                #移动到指定的位置

perform()                                                                    #执行链中的所有动作

release(xcoord, ycoord)                                             #在某个位置松开操作

scroll(xoffset, yoffset)                                                      #滚动到某个位置

scroll_from_element(on_element, xoffset, yoffset)         #从某元素开始滚动到某个位置

tap(on_element)                                                             #单击

tap_and_hold(xcoord, ycoord)                                        #某点按住

为什么要说到移动端,在做登陆时,移动端往往会更加简单,但是触屏版的点击和PC端时完全不同的,点击与按住时不同的。

在某个项目我换成TouchAction后,神奇的发现,注册不再需要处理验证码了,真是太棒了。

使用js

当你使用浏览器已经找到该元素,使用click()方法但是不起作用时,这个时候建议尝试js,例如在我的主页 https://www.zhihu.com/people/cuishite/activities,点击 “查看详细资料”

python js = 'document.getElementsByClassName("Button ProfileHeader-expandButton Button--plain")[0].click();' driver.execute_script(js)

你可以先在控制台调试

js通常可以解决绝大多是问题,如果还是解决不了,那你可能和我遇到了同样的问题,比如说,我在处理某移动端网站登陆,处理如下验证码时,我会使用到move_to_element_with_offset,该方法是“移动到距某个元素(左上角坐标)多少距离的位置”。

计算出坐标后,会调用该方法,如action.move_to_element_with_offset(element, width, height).click().perform(),然而实际上问题并没有这么简单,多次点击失效。具体的有时间再说。

实用方法

提取selenium的cookies

介绍把selenium的cookies船体给requests使用的方法:

cookies = driver.get_cookies()

s = requests.Session()
for cookie in cookies:
    s.cookies.set(cookie['name'], cookie['value'])

How do I load session and cookies from Selenium browser to requests library in Python?

 

元素截图方法

from selenium import webdriver
from PIL import Image

fox = webdriver.Firefox()
fox.get('https://stackoverflow.com/')

# now that we have the preliminary stuff out of the way time to get that image :D
element = fox.find_element_by_id('hlogo') # find part of the page you want image of
location = element.location
size = element.size
fox.save_screenshot('screenshot.png') # saves screenshot of entire page
fox.quit()

im = Image.open('screenshot.png') # uses PIL library to open image in memory

left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']


im = im.crop((left, top, right, bottom)) # defines crop points
im.save('screenshot.png') # saves new cropped image

 selenium cannot screenshot a web element

最后推荐一个神器 appium/python-client

至于验证码部分,现在主要还是靠第三方工具,并没有自己尝试机器学习等方法处理。

 

 

posted @ 2020-03-08 01:52  文强123  阅读(301)  评论(0编辑  收藏  举报