selenium+chorme这个组合初始是用来做自动化测试的,但是因为可以渲染js也可以用来做爬虫,但是效率很低,有利有弊。
安装selenium和chrome驱动
直接pip install selenium安装后
也可通过官网下载安装,下载地址:https://pypi.org/project/selenium/
成功之后可看到版本
下载chromedriver:http://chromedriver.storage.googleapis.com/index.html 或者 https://npm.taobao.org/mirrors/chromedriver
下载的对应包放置python安装目录下(如:D:python)解压即可
selenium快速使用
from selenium import webdriver
import time
import os
# 这里我指定了chromedriver.exe路径,如果放在python根目录下则可以不指定
driver = webdriver.Chrome(executable_path=os.path.abspath("..") + "\\chromedriver.exe")
# 打开网址
driver.get("https://baidu.com")
time.sleep(10)
# 退出浏览器
driver.quit()
这里的全部过程是,创建浏览器并且跳转百度页面,10秒后关闭。
selenium常用定位元素方法
这里定位元素都以百度的搜索框为准
- 通过元素Id属性定位元素
driver.find_element_by_id("kw")
- 通过元素name属性定位元素
driver.find_element_by_name("wd")
- 通过元素class属性定位元素
driver.find_element_by_class_name("s_ipt")
- 通过tag标签定位元素
driver.find_element_by_tag_name("input")
- 通过xpath定位元素
driver.find_element_by_xpath('''//*[@id="kw"]''') # 函数内填写xpah路径,可以是绝对路径,或者属性定位,只要是可用xpath即可
可以在这里搜索元素输入xpath进行定位确认。 - 通过css定位元素
driver.find_element_by_css_selector('''[name='wd']''') # 这里也可以通过css选择器的各种方式例如:通过属性,id,class都可以或者是层级,只要是正确的css都可以还是一样可以去网页中试一下
这边定位元素经常用的方法就是这几种,这是定位单一元素,如果定位很多元素则这样使用:
driver.find_elements_by_tag_name("input")
将find_element_by_tag_name换成find_elements_by_tag_name即可返回多个,其他方法也一样加上s即可
selenium常用元素操作
- send_keys
用于给输入框输入内容,可输入的元素才可以,不然就报错driver.find_elements_by_id("kw").send_keys("guapisansan")
- clear
清空输入框的内容driver.find_element_by_id("kw").clear()
- click
单击鼠标左键,点击操作driver.find_element_by_css_selector("[value='百度一下']").click()
- 下拉框系列
这个博主写的很全,我这里展示三种方法https://blog.csdn.net/LYX_WIN/article/details/119827083
from selenium import webdriver import os driver = webdriver.Chrome(executable_path=os.path.abspath("..") + "\\chromedriver.exe") from selenium.webdriver.support.select import Select # 打开网址 driver.get("http://sahitest.com/demo/selectTest.htm") Select(driver.find_element_by_id("s1Id")).select_by_value("o1") # 通过value属性 Select(driver.find_element_by_id("s2Id")).select_by_index(1) # 通过选项的顺序,第一个为 0 Select(driver.find_element_by_id("s3Id")).select_by_visible_text(" With spaces") # 通过选项可见文本 # 退出浏览器 driver.quit()
- submit
selenium 点击使用的方法就是click(),也有另外一个方法 submit(),好多人会对这两个方法产生误解,认为两种方法是一样的,其实并不是。click()是针对事件的独立性,而 submit() 要求提交对象是一个表单,通常 label 会带有 type = “submit” 这样的属性, 作用于和前,后端的数据互动 或者执行相对应的 action,获取对应的接口 url 等。driver.find_element_by_id('su').submit()
selenium的iframe和窗口切换
可以看到这里的层级关系
- 切到 iframe 页面的常用方法
切iframe的时候一定要注意层级关系,一层一层切换driver.switch_to.frame(0) #根据frame索引切换 driver.switch_to.frame("frame1") # 根据frame名字切换一般为id或者name driver.switch_to.parent_frame() # 切到父级frame driver.switch_to.default_content() # 切到top层,最顶层
- 窗口切换
driver.window_handles # 打印所有窗口句柄,列表 driver.switch_to.window(driver.window_handles[0]) # 切换到第一个窗口 根据索引 driver.current_window_handle # 获取当前所在窗口 driver.maximize_window() # 最大化浏览器 # 创建一个新的窗口用js创建open输入地址 js='window.open("https://www.baidu.com");' driver.execute_script(js) driver.close() # 关闭当前窗口关闭当前网页 直接×掉 driver.quit() # 是关闭整个浏览器
selenium执行JS
selenium支持执行js
# 打开网址
driver.get("https://www.baidu.com")
time.sleep(5)
# 输入瓜皮三三
driver.execute_script('''document.querySelector("#kw").value="瓜皮三三"''')
# 点击百度一下
driver.execute_script('''document.querySelector("#su").click()''')
time.sleep(5)
用jquery一样可以
# 输入瓜皮三三
driver.execute_script('''$("#kw").val("瓜皮三三")''')
# 点击百度一下
driver.execute_script('''$("#su").click()''')
selenium页面等待
-
强制等待(不推荐)
在任何情况都可以使用,但是会影响效率import time time.sleep(10) # 强制等待十秒,效率低
-
隐式等待(不常用)我不喜欢用
设置一个最长的等待时间,等待页面全部元素加载成功则结束,否则异常driver.implicitly_wait(30) # 隐性等待,最长等30秒
-
显示等待(推荐 常用好用我喜欢)
这里最常用的是显示等待,等待你想要的元素,可以自定义很灵活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对象 driver = webdriver.Chrome(executable_path=os.path.abspath("..") + "\\chromedriver.exe") # 打开网址 driver.get("https://www.baidu.com") try: # 显示等待 这里通过By对象的id方法等待id为kw的元素出现则通过 WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located((By.ID, "kw"))) print("搜索框元素加载成功") except TimeoutException: print("搜索框元素加载失败") driver.close()
WebDriverWait的参数为:
driver: 传入WebDriver实例,即我们上例中的driver
timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒until是当某元素出现或什么条件成立则继续执行
until_not是当某元素消失或什么条件不成立则继续执行EC对象的presence_of_element_located是等待元素出现
还有很多其他方法
这里不一一展示了
还可以自定义方法:
例如:
WebDriverWait(driver, 20, 0.5).until(method=lambda d: d.execute_script('''return $('[id="kw"]').length==1;'''))
用method方法定义一个lamdba函数 里面用execute_script方法执行js,返回True或者False
- 也可以自己封装显示等待
即等待超时并不抛出异常避免大量try except。我这里随便举个例子(按照自己的需求)
def wait(presence, visible, by_type, element_name):
try:
if presence:
WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located((by_type, element_name)))
elif visible:
WebDriverWait(driver, 20, 0.5).until(EC.visibility_of_element_located((by_type, element_name)))
return True
except TimeoutException:
return False
wait(presence=True, visible=False, by_type=By.ID, element_name="kw")