Python全栈开发-Python爬虫-13 Selenium自动化与爬虫

Selenium自动化与爬虫

一. selenium自动化介绍与安装

1.1 Selenium自动化介绍

Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏

安装

pip insatll selenium

1.2 Chromedriver的介绍

WebDriver是一个用来进行复杂重复的web自动化测试的工具,可以理解它是谷歌的浏览器的驱动或者插件,自动化selenium提供调用该方法进行自动化的操作


1.3 PhantomJS的介绍

PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的 JavaScript

# 镜像网址:http://npm.taobao.org/mirrors/chromedriver

1.4win安装流程:

1.selenium的安装
# pip install selenium
2.webdriver的下载安装适配
# 1.百度搜索淘宝镜像
# 2.进入搜索结果(点击NPM镜像-NPM下载地址)https://developer.aliyun.com/mirror/NPM?from=tnpm
# 3.选择之后,点击ChromeDriver镜像,和phantomjs镜像
# 4.查看谷歌浏览器版本,右上角三个点(点击)
	# 帮助
    # 关于谷歌
    # 记住谷歌浏览器版本
# 5.在点击进入Chromedriver后,选择版本与谷歌浏览器版本一致或约等于的版本
# 6.点击下载
# 7.解压(获取压缩后的.exe文件)
# 8.将.exe的文件放入python解释器的安装同级目录下(即python.exe的同级目录)
3.测试(成功打开浏览器,进入csdn页面,即安装成功)

from selenium import webdriver

driver = webdriver.Chrome()
driver.get(‘https://www.csdn.net’)

二. selenium的基本使用

2.1 无头模式/无界面模式/后台运行

from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
# 无界面启动,也可以直接设置options.headless=True
option.add_argument("--headless") # 指定无头模式
browser = webdriver.Chrome(options=option)
# 获取浏览器大小
browser.set_window_size(1920, 1080)
# 访问csdn,发送请求
browser.get("https://wwww.baidu.com")
print(browser.page_source)
2.2 加载网页后的常见操作
from selenium import webdriver
# 创建driver对象
driver = webdriver.Chrome()
# 访问的起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
# 将网页生成为图片
driver.save_screenshot("长城.png")
# 根据element内容,id的属性定位
driver.find_element_by_id("kw").send_keys("长城")
driver.find_element_by_id("su").click()
# 获取element的源码内容
driver.page_source
# 打印页面的标题
print(driver.title)
# 获取cookie
driver.get_cookies()
# 退出当前页面
driver.close() 
# 退出浏览器
driver.quit()  
2.3 WebDriver 操作浏览器方式
# 最大化浏览器
	driver.maximize_window()
# 刷新
	driver.refresh()
# 后退
	driver.back()
# 前进
	driver.forward()
# 最大化窗口
	driver.maximize_window()
# 设置浏览器大小
	driver.set_window_size(300,300)
# 设置浏览器位置
	driver.set_window_position(300,200)
# 关闭浏览器单个窗口
	driver.close()
# 关闭浏览器所有窗口
	driver.quit()
2.4 标签定位方法
from selenium import webdriver
driver = webdriver.Chrome()
# 窗口最大化
driver.maximize_window()
url = 'https://www.baidu.com'
driver.get(url)
"""根据标签属性定位"""
# 根据标签属性id定位
# send_keys()  赋值,传入值,输入值
driver.find_element_by_id('kw').send_keys('哥尔赞')
# 根据标签class属性定位
driver.find_element_by_class_name('s_ipt').send_keys('迪迦')
# 根据标签name属性定位
driver.find_element_by_name('wd').send_keys('金刚')
"""根据xpath语法定位"""
driver.find_element_by_xpath('//*[@id="kw"]').send_keys('迪丽热巴')
"""根据CSS语法定位"""
driver.find_element_by_css_selector('#kw').send_keys('林允')

2.5 WebDriver其他常用方法

1. size                 返回元素大小
2. text                 获取元素的文本
3. title                 获取页面title
4. current_url            获取当前页面URL
5. get_attribute("xxx") 获取属性值;xxx:要获取的属性
6. is_display()            判断元素是否可见
7. is_enabled()            判断元素是否可用

提示:

1. size、text、title、current_url:为属性,调用时无括号;如:xxx.size

2. title、current_url:使用浏览器实例化对象直接调用; 如: driver.title

# 获取用户名文本框大小
	size=driver.find_element_by_id("userA").size
	print('size:',size)
# 获取a标签内容
	text=driver.find_element_by_id("fwA").text
	print('a标签text:',text)
# 获取title
	title=driver.title
	print('title:',title)
# 获取当前页面url
	url=driver.current_url
	print('url:',url)
# 获取a标签href属性值
	href=driver.find_element_by_id("fwA").get_attribute("href")
	print('href属性值为:',href)
# 判断span是否显示
	display=driver.find_element_by_css_selector('span').is_displayed()
	print('span标签是否显示:',display)
# 判断取消按钮是否可用
	enabled=driver.find_element_by_id('cancelA').is_enabled()
	print('取消按钮是否可用:',enabled)
6.driver对象的常用属性和方法
driver.page_source		当前标签页浏览器渲染之后的网页源代码
driver.current_url		当前标签页的url
driver.close()			关闭当前标签页,如果只有一个标签页则关闭整个浏览器
driver.quit()			关闭浏览器
driver.forward()		页面前进
driver.back()			页面后退
driver.screen_shot(img_name)	页面截图

三. selenium元素定位

3.1 driver对象定位标签元素获取标签对象的方法

find_element_by_id		             返回一个元素
find_element(s)_by_class_name	     根据类名获取元素列表
find_element(s)_by_name		         根据标签的name属性值返回包含标签对象元素的列表
find_element(s)_by_xpath		     返回一个包含元素的列表
find_element(s)_by_link_text		 根据连接文本获取元素列表
find_element(s)_by_partial_link_text  根据链接包含的文本获取元素列表
find_element(s)_by_tag_name	          根据标签名获取元素列表
find_element(s)_by_css			     根据css选择器来获取元素列表

解析:

find_element和find_elements的区别:

​ 多了个s就返回列表,没有s就返回匹配到的第一个标签对象

​ find_element匹配不到就抛出异常,find_elements匹配不到就返回空列表**

by_link_text和by_partial_link_text的区别:

​ 全部文本和包含某个文本

以上函数的使用方法:

​ driver.find_element_by_id(‘id_str’)

3.2 WebDriver操作鼠标方法

1. context_click()          右击 --> 此方法模拟鼠标右键点击效果
2. double_click()           双击 --> 此方法模拟双标双击效果
3. drag_and_drop()          拖动 --> 此方法模拟双标拖动效果
4. move_to_element()        悬停 --> 此方法模拟鼠标悬停效果
5. perform()                执行 --> 此方法用来执行以上所有鼠标方法

示例:

	1. 导包:from selenium.webdriver.common.action_chains import ActionChains 
	2. 实例化ActionChains对象:Action=ActionChains(driver) 
	3. 调用右键方法:element=Action.context_click(username) 
	4.  执行:element.perform()

3.3 常用的键盘操作

示例:

  • 定位用户名 element=driver.find_element_by_id(“userA”)
  • 输入用户名 element.send_keys(“admin1”)
  • 删除1 element.send_keys(Keys.BACK_SPACE)
  • 全选 element.send_keys(Keys.CONTROL,‘a’)
  • 复制 element.send_keys(Keys.CONTROL,‘c’)
  • 粘贴 driver.find_element_by_id(‘passwordA’).send_keys(Keys.CONTROL,‘v’)

3.4 标签对象提取文本内容和属性值

获取文本 element.text

通过定位获取的标签对象的 text 属性,获取文本内容

获取属性值 element.get_attribute(‘属性名’)

通过定位获取的标签对象的 get_attribute 函数,传入属性名,来获取属性的值

from selenium import webdriver
# 创建driver对象
driver = webdriver.Chrome()
# 访问的起始的url地址
start_url = 'https://www.csdn.net/'
# 访问
driver.get(url=start_url)
result = driver.find_elements_by_tag_name('a')
print(result[1].text)

ret = driver.find_elements_by_link_text('收藏')
print(ret[0].get_attribute('href'))

使用: 以豆瓣首页为例:https://www.douban.com/

  from selenium import webdriver

  driver = webdriver.Chrome()

  driver.get("https://www.douban.com/")

  ret1 = driver.find_element_by_id("anony-nav")
  print(ret1)
  # 输出为:

  ret2 = driver.find_elements_by_id("anony-nav")
  print(ret2)
  #输出为:[]

  ret3 = driver.find_elements_by_xpath("//*[@id='anony-nav']/h1/a")
  print(len(ret3))
   #输出为:1

  ret4 = driver.find_elements_by_tag_name("h1")
  print(len(ret4))
   #输出为:1

  ret5 = driver.find_elements_by_link_text("下载豆瓣 App")
  print(len(ret5))
   #输出为:1

  ret6 = driver.find_elements_by_partial_link_text("豆瓣")
  print(len(ret6))
   #输出为:28

  driver.close()

四. selenium的其他方法

4.1 selenium控制标签页的切换

窗口切换:

​ 获取所有标签页的窗口句柄

​ 利用窗口句柄字切换到句柄指向的标签页

窗口句柄:指的是指向标签页对象的标识

解析:

​ #1.获取当前所有的标签页的句柄构成的列表

​ current_windows = driver.window_handles

​ #2.根据标签页句柄列表索引下标进行切换

​ driver.switch_to.window(current_windows[0])

from selenium import webdriver
import time
# 创建driver对象
driver = webdriver.Chrome()
# 访问的起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
time.sleep(1)
driver.find_element_by_id('kw').send_keys('python')
time.sleep(1)
driver.find_element_by_id('su').click()
time.sleep(1)

# 通过执行js来新开一个标签页
js = 'window.open("https://www.csdn.net");'
driver.execute_script(js)
time.sleep(1)

# 1.获取所有浏览器窗口
windows = driver.window_handles

# 2.根据窗口索引进行切换
driver.switch_to.window(windows[0])
time.sleep(1)
driver.switch_to.window(windows[1])

4.2 selenium控制iframe的切换

iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是driver.switch_to.frame(frame_element)

# 网易邮箱登录

from selenium import webdriver
import time


def login(user, password):
    driver = webdriver.Chrome()
    driver.get("https://email2.163.com/")
    # browser.maximize_window()
    driver.switch_to.frame(driver.find_element_by_xpath('//iframe[starts-with(@id,"x-URS")]'))
    time.sleep(1)

    driver.find_element_by_xpath('//input[@name="email"]').send_keys(user)
    driver.find_element_by_xpath('//input[@name="password"]').send_keys(password)
    driver.find_element_by_xpath('//*[@id="dologin"]').click()

    time.sleep(2)
    print(driver.page_source)
    driver.save_screenshot("163.png")
    time.sleep(3)
    # driver.quit()


if __name__ == '__main__':
    login('163邮箱帐号', '密码')

**driver.switch_to.default_content() --> 恢复默认页面方法 **

​ (在frame表单中操作其他页面,必须先回到默认页面,才能进一步操作)

**1. 跳回最外层的页面 driver.switch_to.default_content() – 切换到最外层(对于多层页面,可通过该方法直接切换到最外层) **

2. 跳回上层的页面 driver.switch_to.parent_frame() – 进行向上的单层切换

Python全栈开发-Python爬虫-13 Selenium自动化与爬虫_第1张图片

切换到定位的frame标签嵌套的页面中

driver.switch_to.frame(通过find_element_by函数定位的frame、iframe标签对象)

利用切换标签页的方式切出frame标签

windows = driver.window_handles

driver.switch_to.window(windows[0])

五. selenium深入学习

5.1 利用selenium获取cookie的方法

获取cookie

​ driver.get_cookies() 返回列表,其中包含的是完整的cookie信息,需要转换为字典

字典推导式转换

​ cookies_dict = {cookie[‘name’]: cookie[‘value’] for cookie in driver.get_cookies()}

Python全栈开发-Python爬虫-13 Selenium自动化与爬虫_第2张图片

删除cookie

  • 删除一条cookie

    ​ driver.delete_cookie(‘cookie_name’)

  • 删除所有的cookie

    ​ driver.delete_all_cookies()

5.2 页面等待

分类:

  • 1.强制等待

    ​ time.sleep()

    ​ 缺点:不智能,设置的时间太短,元素还没有加载出来,设置的时间太长,浪费时间

  • 2.隐式等待

    ​ 针对元素定位,隐式等待设置了一个时间,在一段时间内判断元素是否定位成功,如果完成了,就进行下一步

    ​ 在设置时间内没有定位成功,则会报超时加载

# 隐式等待
from selenium import webdriver
from selenium.webdriver import ChromeOptions
driver = webdriver.Chrome()
# 最多等待你10秒,10秒过后,没有找到就报错
# 一找到,就接着往下执行
driver.implicitly_wait(10)
driver.get('https://www.csdn.net')
  • 3.显示等待

    ​ 明确等待某一个元素,超时则报异常

    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get('https://www.csdn.net')
    # 通过文本名称进行定位
    driver.find_element_by_link_text('人工智能').click()
    
    WebDriverWait(driver, 20, 0.5).until(EC.presence_of_all_elements_located((By.LINK_TEXT, '地图')))
    """
    参数20表示最长等待20s
    参数0.5表示0.5s检查一次规定的标签书否存在
    EC.presence_of_all_elements_located((By.LINK_TEXT, '地图')):通过文本内容定位标签
    每0.5s一次检查,通过链接文本内容定位标签是否存在,如果存在就向下继续执行,如果不存在20s上限就报错
    """
    

手动实现页面等待

原理:

利用强制等待和显示等待的思路来手动实现

不停的判断或有次数限制的判断某一个标签对象是否加载完毕(是否存在)

5.3 selenium控制浏览器执行js代码的方法

执行js的方法:driver.execute_script(js)

Python全栈开发-Python爬虫-13 Selenium自动化与爬虫_第3张图片

5.4 selenium使用代理IP

使用代理ip的方法

  • 实例化配置对象

    • options = webdriver.ChromeOptions()
  • 配置对象添加使用代理ip的命令

    • options.add_argument(’–proxy-server=http://202.20.16.82:9527’)
  • 实例化带有配置对象的driver对象

    • driver = webdriver.Chrome(’./chromedriver’, chrome_options=options)
from selenium import webdriver

# 1.创建一个配置对象
options = webdriver.ChromeOptions()
# 2.使用代理
options.add_argument('--proxy-server=http://192.168.129.130')
# 3.创建driver对象
driver = webdriver.Chrome(options=options)
# 4.设置起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)

5.5 selenium替换user-agent

替换user-agent的方法

  • 实例化配置对象

    • options = webdriver.ChromeOptions()
  • 配置对象添加替换UA的命令

    • options.add_argument(’–user-agent=Mozilla/5.0 HAHA’)
  • 实例化带有配置对象的driver对象

    • driver = webdriver.Chrome(’./chromedriver’, chrome_options=options)
from selenium import webdriver
from fake_useragent import UserAgent
ua = UserAgent()
# 1.创建一个配置对象
options = webdriver.ChromeOptions()
# 2.使用代理
options.add_argument('--user--agent={}'.format(ua.chrome))
# ua = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'
# options.add_argument('user-agent' + ua)
# 3.创建driver对象
driver = webdriver.Chrome(options=options)
# 4.设置起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
print(driver.title)

5.6 拓展知识点

5.6.1 selenium防检测
from selenium import webdriver
from selenium.webdriver import ChromeOptions
 
option = ChromeOptions()     #实例化一个ChromeOptions对象
option.add_experimental_option('excludeSwitches', ['enable-automation'])  #以键值对的形式加入参数
 
bro = webdriver.Chrome(executable_path='./chromedriver.exe',options=option)  #在调用浏览器驱动时传入option参数就能实现undefined

​ 第二种(常用)

driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ })
5.6.2 selenium禁止弹窗
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


chrome_options = Options()

# 禁止弹窗
prefs = {
        'profile.default_content_setting_values':
            {
                'notifications': 2
            }
    }
# 禁止弹窗加入
chrome_options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get(url)
# 就可以访问无通知弹窗的浏览器了
5.6.3 selenium清空输入
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.6.4 selenium模拟回车
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')
# 输出内容:成功回车
5.6.5 selenium下拉框选择
# 导入需要的模块Select()类是用来管理下拉框的
from selenium import webdriver
from selenium.webdriver.support.select import Select
import time
# 创建浏览器对象
driver = webdriver.Chrome()
driver.maximize_window()
# 访问贴吧的高级搜素
driver.get('https://tieba.baidu.com/f/search/adv')

# 定位到下拉框元素
el_select = driver.find_element_by_name('rn')
# 创建一个下拉框对象
xialakuang = Select(el_select)

# 三种方法选择下拉框选项
# 第一、通过选项的索引来选定选项(索引从0开始算)
xialakuang.select_by_index(0)
time.sleep(1)
xialakuang.select_by_index(2)
time.sleep(1)
xialakuang.select_by_index(1)
time.sleep(1)

# 第二种方法:通过option标签的属性值选择
xialakuang.select_by_value('20')
time.sleep(1)
xialakuang.select_by_value('10')
time.sleep(1)
xialakuang.select_by_value('30')
time.sleep(1)

# 第三种:通过文本选择(下拉框的值)
xialakuang.select_by_visible_text('每页显示20条')
time.sleep(1)
xialakuang.select_by_visible_text('每页显示10条')
time.sleep(1)
xialakuang.select_by_visible_text('每页显示30条')
time.sleep(1)

# 打印选择的文本
# 查看第一个已选(若有多个已选则打印第一个,只有一个已选则打印一个)
print(xialakuang.first_selected_option.text)
# 打印所有已选的选项的文本
yixuan = xialakuang.all_selected_options
for i in yixuan:
    print('已选',i.text)
# 打印是否是多选
print(xialakuang.is_multiple)
# 打印所有选项(包括已选和未选的)
m_list = xialakuang.options
for a in m_list:
    print('选项',a.text)

# # 关闭浏览器
# driver.quit()
5.6.6 selenium鼠标悬停
from selenium.webdriver.common.action_chains import ActionChains
# 定位到需要悬停的标签
move = driver.find_element_by_id("xpath语法")
# 开始悬停
ActionChains(self.driver).move_to_element(move).perform()

你可能感兴趣的:(python基础,python,python,selenium,爬虫)