zoukankan      html  css  js  c++  java
  • 通过selenium(也有Puppeter版在最后)登录网页获取特定信息

    前言

    最近有需求要登录网站查询一些信息,然后再修改一些信息,而且这种工作重复性很强,想着通过自动化的方式来做这个东西。

    技术选择

    自动化的方式开始考虑的是用python的爬虫来做,但是登录的网站有好多防爬虫机制,js又是压缩的,登陆的时候post参数就有40多个,后来想过phantomjs但是还是有限制,后来发现了selenium这个自动化测试的工作,尝试了一些感觉用起来相对比较简单,而且python-selenium的官方文档也还行。

    仔细研究了发现,其实selenium这种方式是最简单的也是最low的,这种方式速度很慢,但是相对来讲,我们的需求对速度没有那么大的需求,用selenium完成我们需要的东西最多也就1分钟差不多就能搞定了,又不用研究网站的登录验证。

    还有就是我们想把这个功能放到linux服务器上,selenium需要图形界面还有浏览器的驱动,浏览器的驱动还好说,直接下载然后放到/usr/bin下就行了,但是图形界面有点儿坑,启动就要一段时间,后来在这个上面研究很久,发现了python有pyvirtualdisplay这个插件可以不用装X11这类的图形界面,直接让浏览器启动在虚拟环境中。

    python版本的话,就选择python 2了,因为我们可以在自己笔记本上录制selenium脚本然后转成python脚本,不过录制脚本的浏览器(就是支持selenium ide的浏览器)到现在好像只有Firefox,然后导出的脚本也是python 2的,可以先录制所有的操作,然后自己导出脚本来改动,自己又省了好多事情。

    样例代码

    实际使用过程中还是有些坑,不过也是自己学习的过程,下面上一个样例代码:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import time
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from pyvirtualdisplay import Display
    from selenium.webdriver.chrome.options import Options
    
    
    def reset_mail(dr):
    
        time.sleep(5)
        dr.get('http://mail.163.com')
        dr.find_element_by_id('cred_userid_inputtext').send_keys("wis@163.com")
        dr.find_element_by_id('cred_password_inputtext').send_keys('12345678')
        dr.find_element_by_id('cred_password_inputtext').send_keys(Keys.RETURN)
        # 第一次的回车有时候不太管用,在发送一次回车
        try :
            time.sleep(1)
            dr.find_element_by_id('cred_password_inputtext').send_keys(Keys.RETURN)
        except Exception as e:
            pass
        
        #直接请求需要的url,因为这个时候我们的浏览器driver已经有登录的各种信息了,这个时候我们可以直接dr.get_cookies()把已经登录的cookie拿到,然后直接拿着这个cookies来向我们需要url发送请求,前提是这个请求post的参数比较简单,如果比较复杂的话还是接着往下走吧。
        dr.get('https://portal.partner.microsoftonline.cn/Admin/Default.aspx#ActiveUsersPage')
    
        dr.switch_to.frame(dr.find_elements_by_tag_name('iframe')[0])
        dr.find_element_by_id('EAdminActiveUsersListView_ToolBar_MoveToToolbar').click()
        ele = dr.find_element_by_name('EAdminActiveUsersListView$SearchBox')
        ele.send_keys('hongzhi')
        ele.send_keys(Keys.RETURN)
        my_email = 'hongzhi@163.com'
    
        e1 = WebDriverWait(dr, 10).until(
            EC.presence_of_element_located((By.XPATH, "//td[@title='%s']" % my_email ))
        )
        e1.click()
    
    
        dr.switch_to.frame('DetailPane_detailsFrame')
        dr.find_element_by_id('ViewActiveUsers_contentContainer_lblResetPassword2').click()
    
        dr.switch_to.default_content()
        dr.switch_to.frame('FlyoutIframe')
        time.sleep(1)
        WebDriverWait(dr, 10).until(
                EC.presence_of_element_located((By.ID, "reset-button"))
            ).click()
        WebDriverWait(dr, 10).until(
                EC.presence_of_element_located((By.ID, "response_table"))
            )
        time.sleep(3)
        #找到需要的元素然后打印出来
        pass_ = dr.find_elements_by_xpath("//td")[3].text
        print pass_
    
    
    if __name__ == '__main__':
        display = Display(visible=0,size=(800,600))
        display.start()
        #设置一下浏览器的属性要不然在虚拟环境中启动报错
        chrome_options = Options()
        chrome_options.add_argument("--no-sandbox")
        chrome_options.add_argument("--disable-setuid-sandbox")
        dr = webdriver.Chrome(chrome_options=chrome_options)
        try:
            reset_mail(dr)
        except Exception as e:
            print e
            raw_input("wait:")
            dr.quit()
            display.stop()
        dr.quit()
        display.stop()
    
    

    Puppeter

    现在 selenium 已经快过时了,最近学习了一下 Puppeter, 下面是登陆 dell idrac 做一些操作的代码:

    const puppeteer = require('puppeteer');
    
    (async () => {
      const browser = await puppeteer.launch({headless: false,ignoreHTTPSErrors:true,autoClose:false,});
      let pages = await browser.pages();
      let page = pages[0];
      await page.setViewport({
         1066,
        height: 568,
      });
      await page.goto('https://idrac.wis.com/login.html');
      await page.waitFor(1000);
      await page.waitForSelector('#user',{timeout:5000});
      await page.type('#user', process.env.USER);
      await page.type('#password', process.env.PWD);
      await page.keyboard.down('Enter');
      await page.waitFor(3000);
      await page.waitFor(2000);
      let frame = page.frames().find(frame => frame.name() === 'treelist');
      await frame.waitForSelector("#a_虚拟控制台");
      await frame.click("#a_虚拟控制台");
      await page.waitFor(4000);
      await frame.click("#a_虚拟控制台");
      let frame_console = page.frames().find(frame => frame.name() === 'da');
      await frame_console.waitForSelector("#kvmPluginType");
      // let s = frame_console.$("#kvmPluginType");
      // await s;
    
      await frame_console.select("#kvmPluginType","0");
      await frame_console.select("#kvmSessionTimeoutAction","1");
      const selectElem = await frame_console.$$eval('#kvmSessionTimeoutAction', options => { return options });
      console.log(selectElem);
      console.log(selectElem[0]);
      // console.log(selectElem.value);
      const selectOptions = await frame_console.$$eval('#kvmPluginType  > option', options => { return options.map(option => option.value ) });
      await frame_console.waitFor(5000);
      await frame_console.select("#kvmPluginType","2");
      await frame_console.waitForSelector("#btn_apply_lbl");
      await frame_console.click("#btn_apply_lbl");
      await frame_console.waitForSelector("#launchButton");
      await frame_console.click("#launchButton");
      console.log(selectOptions);
    
      console.log(frame.title());
    
      
      // await browser.close();
    })();
    
    
  • 相关阅读:
    推箱子(简易版)
    [LeetCode] Word Ladder II
    [LeetCode] Path Sum
    [LeetCode] Word Ladder
    DFS & BFS
    [LeetCode] Surrounded Regions
    [LeetCode] Add Binary
    [LeetCode] Plus One
    [LeetCode] Single Number II
    [LeetCode] Single Number
  • 原文地址:https://www.cnblogs.com/WisWang/p/7349576.html
Copyright © 2011-2022 走看看