• 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 " + " ");
    }
    } 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)GoogleChromeApplicationchrome.exe"

    #添加crx插件

    option.add_extension('d:crxAdBlock_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('输入验证码结果: ')

    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

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

  • 相关阅读:
    技术干货 | 闲鱼:一个优秀的 Push 平台,需要经历怎样的前世今生
    钉钉宜搭3.0发布!易连接、酷数据、更安全
    聚焦2021云栖大会,边缘云专场畅谈技术应用创新
    基层数字化治理困境如何破局?
    2021年阿里云双11上云狂欢节亿元加油包提前领攻略
    形式化验证工具TLA+:程序员视角的入门之道
    ArrayList源码浅析
    对云信SDK的研究
    写在当下
    Delphi 正则表达式起步
  • 原文地址:https://www.cnblogs.com/wenqiang-leo/p/12439916.html
Copyright © 2020-2023  润新知