前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬虫篇 | 快速入门selenium(十一)

爬虫篇 | 快速入门selenium(十一)

作者头像
润森
发布2019-08-29 11:17:00
1.6K0
发布2019-08-29 11:17:00
举报

Selenium简介

Selenium是一个用于web自动化测试的工具,Selenium测试直接运行在浏览器中,就好像一个真正的用户在操作一样。

支持大部分主流的浏览器,包括IE(7,8,9,10,11),Firefox,Safari,Chrome,Opera等。

我们可以利用它来模拟用户点击访问网站,绕过一些复杂的认证场景 通过selnium+驱动浏览器这种组合可以直接渲染解析js,绕过大部分的参数构造和反爬。

安装Selenium

Selenium安装非常简单,直接pip就可以搞定: pip install selenium

使用selenium驱动chrome浏览器需要下载chromedriver,而且chromedriver版本需要与chrome的版本对应,版本错误的话则会运行报错。

Chromedriver下载地址:https://chromedriver.storage.googleapis.com/index.html

Windows: 下载对应版本的chromedriver解压后,将文件移动到一个配置了环境变量的文件夹中,例如Python安装文件夹

Linux/Mac: 解压后,将文件移动至/usr/local/bin目录中

测试

基本使用

元素选取


import time
from selenium import webdriver
browser = webdriver.Chrome()
# 打开百度
browser.get('https://www.baidu.com')
# 点击输入框,输入python
browser.find_element_by_xpath('//input[@id="kw"]').send_keys('python')
# 点击百度一下
browser.find_element_by_xpath('//input[@id="su"]').click()
time.sleep(2)
browser.close()

窗口

用selenium操作浏览器如果需要在打开新的页面,这个时候会有问题,因为我们用selenium操作的是第一个打开的窗口,所以新打开的页面我们是无法去操作的,所以我们要用到切换窗口:

handle切换的方法

import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
print(browser.window_handles)
browser.find_element_by_xpath('//div[@id="lg"]').click()
print(browser.window_handles)
browser.switch_to_window(browser.window_handles[-1])
try:
    browser.find_element_by_xpath('//div[@id="3"]/h3/a').click()
finally:
    time.sleep(2)
    browser.quit()

输出:

['CDwindow-4D505E263EB6AACDCB6EB51F9C5CDCCB']
['CDwindow-4D505E263EB6AACDCB6EB51F9C5CDCCB','CDwindow-756C3E21C6EBFA8E470619697053A26E']

并且会关闭第一个页面,即第一个句柄的位置

注意: 如果运行很多次

运行内存很容易挤爆,程序很容易崩毁

import time
from selenium import webdriver
driver = webdriver.Chrome()
# 打开百度
driver.get('https://www.baidu.com')
sreach_window =driver.current_window_handle
try:
    driver.find_element_by_link_text('登录').click()
    time.sleep(2)
    driver.find_element_by_link_text('立即注册').click()
    # 跳转到注册窗口
    for handle in driver.window_handles:
        if handle != sreach_window:
            driver.switch_to_window(handle)
            driver.find_element_by_id('TANGRAM__PSP_3__userName').send_keys('123456789')
finally:
    time.sleep(2)
    driver.quit()

建议将browser.close() 改为 browser.quit()

页面

在实际的爬虫中,有时候我们会遇到找不到元素的问题,明明定位的路径没问题,这个时候我们可以考虑一下是否是该页面存在frame的问题导致的定位不到元素。


import time
from selenium import webdriver
# 实例driver对象
driver = webdriver.Chrome()
# 打开网易邮箱
driver.get('https://mail.163.com/')
sreach_window =driver.current_window_handle
try:
    time.sleep(2)
    driver.switch_to_frame(driver.find_element_by_xpath('//div[@id="loginDiv"]/iframe'))
    driver.find_element_by_name('email').send_keys(123456789)
    time.sleep(2)
    driver.find_element_by_name('password').send_keys('qwe123')
finally:
    time.sleep(2)
    driver.quit()

弹窗切换

有的时候还会遇到弹窗的问题,

主要有两种一种是浏览器弹窗(alert/prompt),一种是自定义弹窗 自定义弹窗,就是一个自定义的div层,是隐藏页面中的,当触发了这个弹窗后,他就显示出来,这种方式我们通过正常的定位方式是可以定位到的。

alert弹窗,就要用下面的方法处理:


import time
from selenium import webdriver
# 实例driver对象
driver = webdriver.Chrome()
# 打开网易邮箱
driver.get('https://www.baidu.com')
try:
    time.sleep(2)
    driver.find_element_by_link_text('设置').click()
    time.sleep(2)
    driver.find_element_by_link_text('搜索设置').click()
    time.sleep(2)
    driver.find_element_by_link_text('保存设置').click()
    time.sleep(2)
    driver.switch_to_alert().accept()
finally:
    time.sleep(5)
    driver.quit()

等待

selenium操作浏览器的过程中,每一次请求url,selenium都会等待页面加载完成以后,才会将操作权限在交给我们的程序。

但是,由于1ajax和各种JS代码的异步加载问题,当一个页面被加载到浏览器时,该页面内的元素可以在不同的时间点被加载,这就使得元素的定位变得十分困难,当元素不再页面中时,使用selenium去查找的时候会抛出ElementNotVisibleException

为了解决这个问题,selenium提供了两种等待页面加载的方式,显示等待和隐式等待,让我们可以等待元素加载完成后在进行操作。隐式等待基本不用

显示等待:

显式等待指定某个条件,然后设置最长等待时间,程序每隔XX时间看一眼,如果条件成立,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出超时异常(TimeoutException)。

WebDriverWait包:from selenium.webdriver.support.wait import WebDriverWait

expected_conditions包:from selenium.webdriver.support import expected_conditions as EC

显示等待主要使用了WebDriverWait类与expected_conditions模块。

一般写法:WebDriverWait(driver, timeout, poll_frequency, igonred_exceptions).until(method, message)

  • Driver: 传入WebDriver实例。
  • timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
  • poll_frequency: 调用until中的方法的间隔时间,默认是0.5秒
  • ignored_exceptions:

忽略的异常,如果在调用until的过程中抛出这个元组中的异常,则不中断代码,继续等待.

  • Method:可执行方法
  • Message:超时时返回的信息
from selenium import webdriver
# 元素定位
from selenium.webdriver.common.by import By
# 等待
from selenium.webdriver.support.wait import WebDriverWait
# 条件
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
try:
    WebDriverWait(driver,20,0.5).until(EC.presence_of_all_elements_located((By.LINK_TEXT,'贴吧')))
    print(driver.find_element_by_link_text('贴吧').get_attribute('href'))
finally:
    driver.quit()

动作链

在selenium当中除了简单的点击动作外,还有一些稍微复杂的动作,就需要用到ActionChains(动作链)这个子模块来满足我们的需求。

ActionChains可以完成复杂一点的页面交互行为,

例如元素的拖拽,鼠标移动,悬停行为,内容菜单交互。

它的执行原理就是当调用ActionChains方法的时候不会立即执行,而是将所有的操作暂时储存在一个队列中,当调用perform()方法的时候,会按照队列中放入的先后顺序执行前面的操作。

导入

from selenium.webdriver.common.action_chains import ActionChains

from selenium import webdriver
from selenium.webdriver.common.action_chains  import ActionChains
import time

driver = webdriver.Chrome()
try:
    driver.get('http://www.treejs.cn/v3/demo/cn/exedit/drag.html')
    time.sleep(2)
    element = driver.find_element_by_id('treeDemo_2_span')
    target = driver.find_element_by_id('treeDemo_3_span')
    ActionChains(driver).drag_and_drop(element, target).perform()
    time.sleep(5)
finally:
    driver.quit()
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小刘IT教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装Selenium
  • 基本使用
  • 窗口
  • 等待
  • 动作链
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档