Selenium
案例
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
if __name__ == '__main__':
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
# 根据id属性找到搜索框
inpot = browser.find_element(By.ID,'kw')
# 输入Python 回车
inpot.send_keys('Python')
inpot.send_keys(Keys.ENTER)
# 等待10秒钟,直至元素出现content_left
wait = WebDriverWait(browser, 10)
wait.until(EC.presence_of_element_located((By.ID, 'content_left')))
print(browser.current_url)
print(browser.get_cookies())
print(browser.page_source)
finally:
# 页面出现后等待3分钟在关闭
time.sleep(300)
browser.quit()
初始化浏览器
selenium提供多种初始化浏览器对象:
from selenium import webdriver browser = webdriver.Chrome() browser = webdriver.Firefox() browser = webdriver.Edge() browser = webdriver.Safari()
访问页面
from selenium import webdriver
browser = webdriver.Chrome()
# 谷歌访问淘宝,打印网页后退出
browser.get('https://www.taobao.com')
print(browser.page_source)
browser.close()
查找节点
在selenium4中的find_element_by_xx被整合成了 find_elemen,根据By.属性获取。
以下是之前的api
单个节点
from selenium import webdriver browser = webdriver.Chrome() # 谷歌访问淘宝 browser.get('https://www.taobao.com') # 访问淘宝搜索框,根据id属性 browser.find_element_by_id('q') # 根据css选择器 browser.find_element_by_css_selector('#q') # 根据xpath browser.find_element_by_xpath('//*[@id="q"]')
更多获取单个节点:
- find_element_by_id
- find_element_by_name
- find_element_by_xpath
- find_element_by_link_text
- find_element_by_partial_link_text
- find_element_by_tag_name
- find_element_by_class_name
- find_element_by_css_selector
全部在find_element下使用,用By属性选择内容
from selenium.webdriver.common.by import By from selenium import webdriver browser = webdriver.Chrome() # 谷歌访问淘宝 browser.get('https://www.taobao.com') # 访问淘宝搜索框,根据id属性 browser.find_element(By.id,'q')
多个节点
使用find_element只能返回得到的第一个节点,可以选择使用find_elements获取多个节点,使用属性By.CSS_SELECTOR
节点交互
常用的方法:用send_keys输入文字,使用clear清空文字,用click点击按钮
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
# 访问淘宝
browser.get('https://www.taobao.com')
# 获取输入框
inpot = browser.find_element(By.ID, 'q')
# 输入ipad
inpot.send_keys('iPad')
# 等待3秒
time.sleep(3)
# 清空输入框
inpot.clear()
# 输入iPhone
inpot.send_keys('iPone')
#找到搜索框点击
but = browser.find_element(By.CLASS_NAME,'btn-search')
but.click()
browser.close()
动作链
除了一些针对某个节点执行的交互方法,还有动作链,它们没有特定的执行对象,比如鼠标拖拽、键盘按键等
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
# 切换到右侧页面
browser.switch_to.frame('iframeResult')
# 获取两个元素
source = browser.find_element(By.ID, 'draggable')
target = browser.find_element(By.ID, 'droppable')
# 将浏览器对象给ActionChains对象
actions = ActionChains(browser)
# 传递元素,将元素拖拽目标元素位置
actions.drag_and_drop(source, target)
# 执行动作
actions.perform()
相关动作api:
from selenium.webdriver import ActionChains # 创建ActionChains实例 actions = ActionChains(driver) # 将鼠标移动到某个元素上 actions.move_to_element(element) # 模拟鼠标左键单击操作 actions.click() # 在某个元素上按下鼠标左键并保持按下状态 actions.click_and_hold(element) # 释放鼠标左键 actions.release() # 模拟鼠标右键单击操作 actions.context_click() # 拖拽一个元素到另一个元素处 actions.drag_and_drop(source_element, target_element) # 在某个元素上按下某个键盘键,并释放 actions.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL)
运行JavaScript
例如拖动下拉框时,需要模拟实现js,可以使用execute_script方法
browser.get('https://www.zhihu.com/explore') # 进度条拉到最底部 browser.execute_script('window.scrollTo(0,document.body.scrollHeight)') browser.execute_script('alert("To Bottom")')
获取节点信息
获取属性
先使用find_element方法获取属性后,可以使用get_attribute()方法获取属性
browser.get('https://www.zhihu.com/') main = browser.find_element(By.CLASS_NAME, 'App-main') print(main.get_attribute('role'))
获取文本值
获取文本值内容,和pyquery类似,直接使用text属性
获取相关信息
- id属性:用于获取节点ID
- location属性:后去节点在页面中的相对位置
- tag_name属性:获取标签的名称
- size属性:获取节点的大小,就是宽高。
切换Frame
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
browser=webdriver.Chrome()
url='https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
# 切换到子页面
browser.switch_to.frame('iframeResult')
try:
logo=browser.find_element(By.CLASS_NAME,'logo')
except NoSuchElementException:
print('NO LOGO')
# 返回父页面
browser.switch_to.parent_frame()
logo=browser.find_element(By.CLASS_NAME,'logo')
print(logo)
print(logo.text)
延时等待
在selenium中,get方法在网页框架加载结束后才会结束执行,如果尝试在get方法执行完毕时获取网页源代码,其结果可能并不是浏览器完全加载完成的页面。因为某些页面有额外的ajax请求,页面还有由JavaScript渲染。所以必要时间需要设置浏览器延时等待,确保节点已经加载
隐式等待
使用隐式等待执行测试时,如果selenium没有在DOM中找到节点,将继续等待,在超出设定时间后,抛出找不到节点的异常。
from selenium import webdriver from selenium.webdriver.common.by import By browser = webdriver.Chrome() browser.implicitly_wait(10) browser.get('https://spa2.scrape.center/') input = browser.find_element(By.ID,'logo-image') print(input)
使用了implicitly_wait使用了隐式等待。
显式等待
指定查找的节点和最长等待时间。如果在规定时间内加载出了要查找的节点,就返回这个节点;如果到了规定时间依然没有加载出节点,就抛出超时异常。
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium import webdriver from selenium.webdriver.common.by import By browser = webdriver.Chrome() browser.get('https://www.taobao.com/') wait = WebDriverWait(browser,10) # 代表节点出现,如果q节点的搜索框在10秒钟加载出来,反之抛出异常 input = wait.until(EC.presence_of_element_located((By.ID,'q'))) # 代表按钮可点击,如果按钮在十秒钟加载出来则返回,反之抛出异常 button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search'))) print(input,button)
相关等待条件:
等待条件 | 含义 |
---|---|
title_is | 标题是某内容 |
title_contains | 标题包含某内容 |
presence_of_element_located | 节点出现,参数为节点的定位元组,如(By.ID,'p') |
visibility_of_element_located | 节点可见,参数为节点的定位元组 |
visibility_of | 可见,参数为节点对象 |
presence_of_all_element_located | 所有节点都出现 |
text_to_be_present_in_element | 某个节点的文本值包含某文字 |
text_to_be_present_in_element_value | 某个节点值中包含某文字 |
frame_to_be_available_and_switch_to_it | 加载并切换 |
invisibility_of_element_located | 节点不可见 |
element_to_be_clickable | 按钮可点击 |
staleness_of | 判断一个节点是否仍在DOM数中,可知页面是否已经刷新 |
element_to_be_selected | 节点可选择,参数为节点对象 |
element_located_to_be_selected | 节点可选择,参数为节点的定位元组 |
element_selection_state_to_be | 参数为节点对象以及状态,相等返回True,反之False |
element_located_selection_state_to_be | 参数为定位元组以及状态,相等返回True,反之False |
alert_is_present | 是否出现警告提示框 |
前进和后退
浏览器中的前进后退功能,使用forward方法前进,back方法后退
from selenium import webdriver import time browser = webdiver.Chrome() browser.get('https://www.baidu.com/') browser.get('https://www.taobao.com/') browser.get('https://www.python.org/') browser.back() time.sleep(1) browser.forward() browser.close()
Cookie
对Cookie进行操作,例如获取、添加、删除等。
from selenium import webdriver browser = webdiver.Chrome() browser.get('https://www.zhuhu.com/explore') # 获取Cookie print(browser.get_cookies()) # 添加Cookie browser.add_cookie({'name':'name','domin':'www.zhihu.com','value':'germey'}) print(browser.get_cookies()) # 删除所有的Cookie browser.delete_all_cookies()
选项卡处理
from selenium import webdriver
import time
browser = webdiver.Chrome()
browser.get('https://www.baidu.com')
# 使用js打开一个新窗口
browser.execute_script('window.open()')
# 获取当前窗口的所有选项卡
print(browser.window_handles)
# 根据索引切换窗口
browser.switch_to.window(browser.window_handles[1])
browser.get('https://www.taobao.com')
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
browser.get('https://python.org')
反屏蔽
标签:基本,webdriver,selenium,Selenium,element,import,用法,节点,browser From: https://www.cnblogs.com/kangkin/p/17379504.html很多网站增加selenium检测,检测当前的浏览器窗口window.navigator对象是否包含webdriver属性。
如果想在访问前利用execute_script将window.navigator中包含的webdriver清空,页面在渲染前就检测到了
可以利用CDP(Chrome开发工具协议),在每个页面加载时执行js语句,将webdriver清空Page.addScriptToEvaluateOnNewDocument
from selenium import webdriver from selenium.webdriver import ChromOptions option = ChromeOptions() option.add_experimental_option('excludeSwitches',['enable-automation']) option.add_experimental_option('useAutomationExtension',False) browser = webdriver.Chrome(optaions=option) # 将webdriver属性置空 browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',{ 'source':'Object.defineProperty(navigator,"webdriver",{get:()=>undefined})' }) browser.get('https://antispider1.scrape.center/')