分享

Selenium 常用代码及 Tips

 达坂城大豆 2017-11-27

作者:东东

来源:https://blog.

(一)判断元素是否存在

  1. self.driver.find_element(By.ID, 'name').size != 0

(二)智能延时/等待指定节点加载

当需要获取的元素节点是由 JavaScript 动态生成时,需要让获取节点的代码'等一等'再运行 通过 time.sleep(5)这种方式,当需要等待网络请求比较多时,会导致完成一次运行需要等待很久,如下是一些代码及使用场景

每次点击事件后都应该添加智能延时代码,它会等待时间为0~5秒

  1. from selenium import webdriver

  2. from selenium.webdriver.common.by import By

  3. driver = webdriver.Firefox()

  4. driver.get('http://www./')

  5. driver.find_element(By.ID, 'submit').click()

  6. driver.implicitly_wait(5)

一般来讲,稍稍设置大一些的等待时间即可加载出相应节点的数据,有一种更为确定的方法,可以在指定的时间内等待,直到我们需要的节点加载出来,相比于 implicitly_wait 它更加的精确,节省时间,因为它不必等待我们不关心的节点加载

  1. from selenium import webdriver

  2. from selenium.webdriver.common.by import By

  3. from selenium.webdriver.support.ui import WebDriverWait

  4. from selenium.webdriver.support import expected_conditions as EC

  5. driver = webdriver.Firefox()

  6. driver.get('http://www./')

  7. wait = WebDriverWait(self.driver, 10)

  8. wait.until(

  9.    EC.presence_of_element_located((By.ID, 'submit'))

  10. ).click()

如上的写法是针对于获取到节点就点击的,如果一个登陆表单时动态加载的,并且里面的元素也是动态加载的,那么首先需要先获取登陆表单,然后在表单的基础上再选择节点,示例代码段如下

  1. # 等待登录页加载完成

  2. wait = WebDriverWait(driver, WAIT_TIME)

  3. formElement = wait.until(

  4.    EC.presence_of_element_located((By.CSS_SELECTOR, '.sign-in-form'))

  5. )

  6. # 填写邮箱与密码登陆

  7. emailElement = formElement.find_element(By.ID, 'email')

  8. emailElement.send_keys(username)

  9. passwordEmement = formElement.find_element(By.ID, 'password')

  10. passwordEmement.send_keys(password)

  11. # 点击登陆

  12. formElement.find_element(By.CSS_SELECTOR, '[type='button']').click()

  13. driver.implicitly_wait(WAIT_TIME)

(三)元素个数(Elements Counts)

一些情况下,获取元素下子节点的数量有助于帮助程序判断节点的状态,简化代码,而且有时数量信息也是很重要的数据

  1. counts = self.driver.find_elements(By.CLASS_NAME, 'img')

  2. print len(counts)

为了这个问题,我Google了有一会,有说需要使用xpath才能返回列表的,有的是java的代码,尝试好久,最后我才在一个问题下边猛然的发现我的方法少了一个 s,是 find_elements_by_xxx()而不是 find_element_by_xxx()

(四)处理iframe的情况

driver.switchtoframe(self, frame_reference) 这个方法已经废弃

新的函数如下:

  1. def frame_switch(css_selector):

  2.    driver.switch_to.frame(driver.find_element_by_css_selector(css_selector))

  3. def frame_switch(name):

  4.  driver.switch_to.frame(driver.find_element_by_name(name))

处理完iframe,回到之前的界面

  1. driver.switch_to.default_content()

(五)Firefox与Chrome的driver差异

当写完Login()函数后,加载其它函数,比如或许用户详情页的时候,Firefox Driver或自动带上Cookies,Chrome Driver 不会自动加载Cookies,所以使用Chrome比Firefox需要多两行代码,手动加载Cookies

  1. # 登陆后获取cookies

  2. cookies = driver.get_cookies()

  3. # 在加载新的页面后倒入Cookies

  4. for cookie in cookies:

  5.    driver.add_cookie(cookie)

如果有些网站的Cookies有效期很长,那么可以将Cookies保存到文件

  1. # 保存Cookies到文件

  2. import pickle

  3. import selenium.webdriver

  4. driver = selenium.webdriver.Firefox()

  5. driver.get('http://www.google.com')

  6. pickle.dump( driver.get_cookies() , open('cookies.pkl','wb'))

  7. # 从文件加载Cookies

  8. import pickle

  9. import selenium.webdriver

  10. driver = selenium.webdriver.Firefox()

  11. driver.get('http://www.google.com')

  12. cookies = pickle.load(open('cookies.pkl', 'rb'))

  13. for cookie in cookies:

  14.    driver.add_cookie(cookie)

(六)滚动加载

有些数据一页展示不完,当侧边栏向下拉或者鼠标滚动的时候才会继续加载数据,这种模式在瀑布流的图片展示站点非常常见,不过也很好解决

  1. # 回到顶部

  2. js='var q=document.body.scrollTop=0'

  3. driver.execute_script(js)

  4. # 拉到底部

  5. js='var q=document.body.scrollTop=10000'

  6. driver.execute_script(js)

在网上搜索的时候有这样的写法 document.documentElement.scrollTop=10000,我在测试的时候发现body的写法是工作的,这可能跟网站/浏览器 有一定关系,在测试的时候哪种能工作就用哪种吧


题图:pexels,CC0 授权。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多