爬虫基础(笔记)——4.Selenium与验证码识别

 

目录

 ​​​​Selenium(WEB自动化工具)

准备工作

下载selenium包

 下载浏览器驱动

基本操作

对象定位方法

三种等待方式

强制等待

隐性等待

显性等待

浏览器操作

浏览器最大化、最小化

浏览器设置窗口大小

浏览器前进后退、窗口选择

操作测试对象

键盘事件

鼠标事件

多层框架/层级定位

下拉列表

执行JavaScript代码

无头浏览器

Expected Conditions解析

使用场景

相关方法

示例

selenium规避检测--------浏览器托管

验证码


​​​​Selenium(WEB自动化工具)

  • 准备工作

下载selenium包

pip install selenium

如遇网络问题可改源: pip install selenium -i 清华源

 下载浏览器驱动

注意找对应浏览器版本的驱动,下载解压完成后将驱动文件(重命名去掉后面的数字)复制进python解释器所在文件夹下

Edge浏览器驱动网站:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/#installation

 

  • 基本操作

#导入包
from selenium.webdriver import Edge

#创建一个浏览器对象
browser = Edge()

#打开一个网址
browser.get("https://www.baidu.com")

#打印标签页名称
print(browser.title)

#打印页面源代码
print(browser.page_source())

#退出驱动,关闭所有窗口
browser.quit()

 

  • 对象定位方法

webdriver 提供了一系列的对象定位方法,常用的有以下几种:

#xpath定位:find_element_by_xpath()

#id定位:find_element_by_id()

#name定位:find_element_by_name()

#class定位:find_element_by_class_name()

#link定位:find_element_by_link_text()

#partial link定位:find_element_by_partial_link_text()

#tag定位:find_element_by_tag_name()

#css定位:find_element_by_css_selector()

#(将element改为elements将匹配所有的对应元素,类似正则匹配里find和find_all的关系)

 

在实际进行元素定位时,经常发现class name是有多个class组合的复合类,中间以空格隔开。如果直接进行定位会出现报错,可以通过以下方式处理:

1.class属性唯一但是有空格,选择空格两边唯一的那一个

2.若空格隔开的class不唯一可以通过索引进行定位

self.browser.find_elements_by_class_name('table-dragColumn')[0].click()

3.通过css方法进行定位(空格以‘.’代替)

self.browser.find_element_by_css_selector('.dtb-style-1.table-dragColumns').click()

包含整个类self.browser.find_element_by_css_selector('class="dtb-style-1 table-dragColumns"').click()

 

  • 三种等待方式

有时候为了保证脚本运行的稳定性,需要脚本中添加等待时间。

强制等待

第一种也是最简单粗暴的一种办法就是强制等待sleep(xx),需要引入“time”模块。time.sleep(3),不管你浏览器是否加载完了,程序都得等待3秒,3秒一到,继续执行下面的代码,作为调试很有用,有时候也可以在代码里这样等待,不过不建议总用这种等待方式,太死板,严重影响程序执行速度。

隐性等待

第二种办法叫隐性等待,通过添加 implicitly_wait() 方法就可以方便的实现智能等待。browser.implicitly_wait(30) 的用法应该比 time.sleep() 更智能,后者只能选择一个固定的时间的等待,前者可以 在一个时间范围内智能的等待。

隐形等待是设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步。注意这里有一个弊端,那就是程序会一直等待整个页面加载完成,也就是一般情况下你看到浏览器标签栏那个小圈不再转,才会执行下一步,但有时候页面想要的元素早就在加载完成了,但是因为个别js之类的东西特别慢,我仍得等到页面全部完成才能执行下一步,我想等我要的元素出来之后就下一步怎么办?有办法,这就要看selenium提供的另一种等待方式——显性等待wait了。

需要特别说明的是:隐性等待对整个driver的周期都起作用,所以只要设置一次即可

显性等待

第三种办法就是显性等待,WebDriverWait类,配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了。它主要的意思就是:程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException。

from selenium import webdriver

from selenium.webdriver.support.wait import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.common.by import By

driver = webdriver.Edge()

driver.implicitly_wait(10) # 隐性等待和显性等待可以同时用,但要注意:等待的最长时间取两者之中的大者

driver.get('https://huilansame.github.io')

locator = (By.LINK_TEXT, 'CSDN')

try:
    WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
finally:
    driver.close()

如果想深入研究WebDriverWait类,可参考:https://www.jb51.net/article/92672.htm

 

  • 浏览器操作

浏览器最大化、最小化

#将浏览器最大化显示

browser.maximize_window()

#将浏览器最小化显示

browser.minimize_window()

 

浏览器设置窗口大小

#设置浏览器宽480、高800显示

browser.set_window_size(480, 800)

浏览器前进后退、窗口选择

#前进

browser.forword()

#后退

browser.back()

#切换到最后一个标签页窗口

browser.switch_to_window(browser.window_handles[-1])

#关闭当前窗口

browser.close()

#退出驱动关闭所有窗口

browser.quit()

 

  • 操作测试对象

一般来说,webdriver 中比较常用的操作对象的方法有下面几个:

click——点击对象

send_keys——在对象上模拟按键输入

clear——清除对象的内容,如果可以的话

submit——提交对象的内容,如果可以的话

text——用于获取元素的文本信息

 

  • 键盘事件

#要想调用键盘按键操作需要引入 keys 包

from selenium.webdriver.common.keys import Keys

#通过 send_keys()调用按键

send_keys(Keys.TAB) # TAB
send_keys(Keys.ENTER) # 回车

 

  • 鼠标事件

鼠标事件一般包括鼠标右键、双击、拖动、移动鼠标到某个元素上等等,需要引入ActionChains类。ActionChains 常用方法:

#perform() 执行所有ActionChains 中存储的行为

#context_click() 右击

#double_click() 双击

#drag_and_drop() 拖动

#move_to_element() 鼠标悬停

示例 :

#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains

#创建动作链
action = ActionChains(browser)

#鼠标双击示例:

#定位到要双击的元素
qqq =browser.find_element_by_xpath("xxx")

#对定位到的元素执行鼠标双击操作 
action.double_click(qqq).perform()

#鼠标拖放示例:

#定位元素的原位置 
element = browser.find_element_by_name("source") 

#定位元素要移动到的目标位置 
target = browser.find_element_by_name("target")

#执行元素的移动操作 
action.drag_and_drop(element, target).perform()

 

  • 多层框架/层级定位

定位元素过程中经常会遇到找不到元素的问题,出现该问题一般都是以下因素导致:

1.元素定位方法不对

2.页面存在iframe或内嵌窗口

3.页面超时


webdriver 提供了一个 switch_to_frame 方法,可以很轻松的来解决这个问题。用法:

#先找到 ifrome1(id = f1)

browser.switch_to_frame("f1")

#同样的,如果是内嵌窗口

browser.switch_to_window("f1")

#想切回来

browser.switch_to.default_content()

 

  • 下拉列表

#导入对应包
from selenium.webdriver.support.select import Select

#定位到下拉列表
list = browser.find_element_by_xpath("...")

#对元素进行包装,包装成下拉列表
sel = Select(list)


#所有选项sel.options()

#根据索引切换sel.select_by_index()
#根据value的值切换sel.select_by_value()
#根据文本显示内容切换sel.select_by_visible_text()

 

  • 执行JavaScript代码

browser.execute.script()

 

  • 无头浏览器

#需要导入包
from selenium.webdriver.Edge.options import Options


#创建一个参数对象,用来控制edge以无界面模式打开
edge_options = Options()

#无头浏览器参数配置
edge_options.add_argument("--headless")
edge_options.add_argument("--disable-gpu")

#把参数配置放入浏览器中,创建浏览器对象
browser = Edge(options = edge_options)

 

  • Expected Conditions解析

使用场景

1.直接在断言中使用

2.与WebDriverWait配合使用,动态等待页面上元素出现或者消失


相关方法

title_is: 判断当前页面的title是否精确等于预期

title_contains: 判断当前页面的title是否包含预期字符串

presence_of_element_located:判断某个元素是否被加到了dom树里,并不代表该元素一定可见

visibility_of_element_located:判断某个元素是否可见.可见代表元素非隐藏,并且元素的宽和高都不等于0

visibility_of:跟上面的方法做一样的事情,只是上面的方法要传入locator,这个方法直接传定位到的element就好了

presence_of_all_elements_located:判断是否至少有1个元素存在于dom树中。举个例子,如果页面上有n个元素的class都是'column-md-3',那么只要有1个元素存在,这个方法就返回True

text_to_be_present_in_element:判断某个元素中的text是否包含了预期的字符串

text_to_be_present_in_element_value:判断某个元素中的value属性是否包含了预期的字符串

frame_to_be_available_and_switch_to_it:判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False

invisibility_of_element_located:判断某个元素中是否不存在于dom树或不可见

element_to_be_clickable:判断某个元素中是否可见并且是enable的,这样的话才叫clickable

staleness_of:等某个元素从dom树中移除,注意,这个方法也是返回True或False

element_to_be_selected:判断某个元素是否被选中了,一般用在下拉列表

element_selection_state_to_be:判断某个元素的选中状态是否符合预期

element_located_selection_state_to_be:跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入locator

alert_is_present:判断页面上是否存在alert

 

示例

"""
思路:

1.判断title:title_is()、title_contains()

2.导入expected_conditions模块。由于这个模块名称比较长,所以为了后续的调用方便,重新命名为EC了(有点像数据库里面多表查询时候重命名)

3.打开博客首页后判断title,返回结果是True或False
"""


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

driver = webdriver.Firefox()driver.get("URL")

# 判断title完全等于
title = EC.title_is(u'冰封')
print title(driver)

# 判断title包含
title1 = EC.title_contains(u'冰封')
print title1(driver)


# 另外一种写法
r1 = EC.title_is(u'冰封')(driver)
r2 = EC.title_contains(u'冰封')(driver)
print r1
print r2

 

  • selenium规避检测--------浏览器托管

 

验证码

破解方法:

1.图像识别

2.互联网上比较成熟的验证码破解工具,如:超级鹰 http://www.chaojiying.com/about.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值