Selenium使用

如果爬虫不会Selenium 就不要说自己会爬虫

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下载地址:

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()

补充:

截图

全屏截图

driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
# driver.get_screenshot_as_file('1.png')
driver.save_screenshot('1.png')
driver.close()

在这里插入图片描述

截图元素图片

try:
    element = driver.find_element_by_id('lg')
    element.screenshot('element.png')
    print(element.location)
    print(element.size)
finally:
    driver.close()

在这里插入图片描述

区域截图

需要导入PIL

from selenium import webdriver
from time import sleep
from PIL import Image
# 时间格式进行格式化
driver = webdriver.Chrome()
driver.get('http://www.baidu.com/')
# 要截屏的目标元素
element = driver.find_element_by_id("su")
print(element.location)
print(element.size)
# 获取element的顶点坐标
xPiont = element.location['x']
yPiont = element.location['y']
# 获取element的宽、高
element_width = xPiont + element.size['width']
element_height = yPiont + element.size['height']
picture = Image.open('1.png')
picture = picture.crop((xPiont, yPiont, element_width, element_height))
picture.save("1.png")
sleep(2)
driver.quit()

在这里插入图片描述

聚彩汇彩票计划群 山东11选5开奖 谁有极速赛车稳赚的方法 五福彩票计划群 福布斯彩票计划群 快赢彩票计划群 万彩会彩票计划群 极速赛车登陆 淘彩票计划群 上海11选5开奖