说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Selenium (读作 [səˈliːniəm],n. 硒)是一个 Web 自动化测试工具,可以直接运行在浏览器上, Selenium 可以根据代码指令让浏览器自动加载页面,模拟登录、代替人工执行操作,特点是得到的这些页面源码是经过浏览器渲染之后的。
相关网站:github 和 pypi 和 帮助文档 和 官网。
Selenium 不自带浏览器,除了 Python 包安装外,还需要安装浏览器驱动。
模块安装:
pip install -U selenium
浏览器驱动安装:
所下载的版本要与电脑上安装的相应浏览器的版本一致。下载后,以 Chrome 为例,会有一个 chromedriver 名的文件(火狐是 geckodriver):
注:如 MAC 提示 macOS无法验证此App不包含恶意软件(macOS cannot verify that this app is free from malware.),需要在电脑系统设置中的安全与隐私中的一般设置中允许非应用商店的应用安装。
也可以不采用上边的操作,在后续代码中指定驱动文件的位置。注意,一定要下载对应操作系统的版本,否则会有如下提示:
OSError: [Errno 8] Exec format error: '/usr/local/bin/geckodriver'
如果遇到以下错误:
“chromedriver” cannot be opened because the developer cannot be verified.
需要执行:
cd /usr/local/bin
xattr -d com.apple.quarantine chromedriver
以下是一个简单的访问操作:
from selenium import webdriver
from selenium.webdriver import FirefoxOptions
opts = FirefoxOptions()
opts.add_argument("--headless") # 无头浏览器
# browser = webdriver.Chrome()
browser = webdriver.Firefox(options=opts)
# 指定浏览器驱动
# b = webdriver.Firefox(executable_path='/usr/local/bin/geckodriver')
browser.get('https://www.baidu.com')
browser.page_source # 输出源码
browser.title # 网页标量
browser.close()
browser.quit()
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import presence_of_element_located
#This example requires Selenium WebDriver 3.13 or newer
with webdriver.Firefox() as driver:
wait = WebDriverWait(driver, 10)
driver.get("https://google.com/ncr")
driver.find_element(By.NAME, "q").send_keys("cheese" + Keys.RETURN)
first_result = wait.until(presence_of_element_located(By.CSS_SELECTOR, "h3>div"))
print(first_result.get_attribute("textContent"))
浏览网页后,可以通过以下方法再获取网页中的元素:
# 推荐用这个
browser.find_elements('id', 'login')
# 更多选择
browser.find_element(by='id', value=None) # 以下省略 browser.
find_element_by_class_name(name)
find_element_by_css_selector(css_selector)
find_element_by_id(id_)
find_element_by_link_text(link_text)
find_element_by_name(name)
find_element_by_partial_link_text(link_text)
find_element_by_tag_name(name)
find_element_by_xpath(xpath)
# 以下返回多个,列表
find_elements(by='id', value=None)
find_elements_by_class_name(name)
find_elements_by_css_selector(css_selector)
find_elements_by_id(id_)
find_elements_by_link_text(link_text)
find_elements_by_name(name)
find_elements_by_partial_link_text(link_text)
find_elements_by_tag_name(name)
find_elements_by_xpath(xpath)
# Returns the WebElement wrapped by this EventFiringWebElement instance
wrapped_element
# iframe 框
browser.switch_to.frame(0) # index 索引来定位,第一个是0
browser.switch_to.frame("frame_id") # id 来定位
browser.switch_to.frame("frame_name") # name 来定位
# WebElement 对象来定位
browser.switch_to.frame(b.find_elements('id', 'frame_id'))
常用:
find_element_by_xpath('//input[@placeholder="请输入用户名"]')
browser.forward() # 向前
browser.back() # 返回
browser.fullscreen_window() # 全屏
browser.maximize_window() # 最大化
browser.minimize_window() # 最小化
browser.get_screenshot_as_file('web.png') # 截图, 文件
browser.get_screenshot_as_png()
browser.get_screenshot_as_base64()
elem = browser.find_element_by_id('userName')
elem.clear()
elem.click() # 点击
elem.send_keys(*value) # 填写内容
browser.find_element_by_id("form1").submit() # 表单提交
from selenium.webdriver.common.keys import Keys
elem.send_keys(Keys.ESCAPE) # 返回键,失焦
elem.send_keys(" and some", Keys.ARROW_DOWN) # 单击向下箭头
elem.send_keys(Keys.RETURN) # 回车
鼠标操作:
from selenium.webdriver.common.action_chains import ActionChains
searchElement = driver.find_element_by_id('sb_form_q').send_keys('selenium')
searchButtonElement = driver.find_element_by_id('sb_form_go')
ActionChainsDriver = ActionChains(driver).click(searchButtonElement) #分开两步进行书写
ActionChainsDriver.perform()
# ActionChains 提供的方法
click(on_element=None) # 单击鼠标左键
click_and_hold(on_element=None) # 点击鼠标左键,按住不放
context_click(on_element=None) # 点击鼠标右键
double_click(on_element=None) # 双击鼠标左键
drag_and_drop(source, target) # 拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset) # 拖拽到某个坐标然后松开
move_by_offset(xoffset, yoffset) # 鼠标移动到距离当前位置(x,y)
move_to_element(to_element) # 鼠标移动到某个元素
move_to_element_with_offset(to_element, xoffset, yoffset) # 将鼠标移动到距某个元素多少距离的位置
release(on_element=None) # 在某个元素位置松开鼠标左键
perform() # 执行链中的所有动作
browser.execute_script('window.scrollTo(0,0);') # 操作滚动条
# 滚动到底部
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 设置 Cookies,对整个域
cookie = {'name' : 'foo', 'value' : 'bar'}
browser.add_cookie(cookie)
# 获取 Cookies
browser.get_cookies()
# 删除 Cookies
browser.delete_all_cookies()
将各种方式获取元素的进行封装,以类似 get_by_browser('class:class_name')
进行调用:
def get_by_browser(browser, by):
by_kv = by.split(':')
k, v = by_kv[0], by_kv[1]
by_case = {
"id": lambda x: browser.find_element_by_id(x),
"name": lambda x: browser.find_element_by_name(x),
"xpath": lambda x: browser.find_element_by_xpath(x),
"link_text": lambda x: browser.find_element_by_link_text(x),
"partial_link_text": lambda x: browser.find_element_by_partial_link_text(x),
"tag_name": lambda x: browser.find_element_by_tag_name(x),
"class_name": lambda x: browser.find_element_by_class_name(x),
"css_selector": lambda x: browser.find_element_by_css_selector(x)
}
try:
browser = by_case[k](v)
except KeyError as e:
browser = browser.find_element_by_tag_name('html')
return browser
以上边的功能也可用以下方式实现:
from selenium.webdriver.common.by import By
# browser.find_element(by='id', value=None)
browser.find_element(By.ID, "content")
网页渲染后,单纯的 HTTP 请求可以使用 Requests 库来操作。还有种情况中,登录有复杂的验证码如拖动图像块、手机验证码等,需要 selenium 配合并人工完成,登录之后再用 Requests 访问数据。
import requests
s = requests.Session()
selenium_user_agent = browser.execute_script("return navigator.userAgent;")
s.headers.update({"user-agent": selenium_user_agent})
for cookie in browser.get_cookies():
s.cookies.set(cookie['name'], cookie['value'], domain=cookie['domain'])
# 发起访问请求
r = s.get(target_url)
# browser.delete_all_cookies()
另外,上述登录验证码问题:
browser 对象的方法:
browser.add_cookie
browser.application_cache
browser.back
browser.capabilities
browser.close
browser.command_executor
browser.create_options
browser.create_web_element
browser.current_url
browser.current_window_handle
browser.delete_all_cookies
browser.delete_cookie
browser.desired_capabilities
browser.error_handler
browser.execute
browser.execute_async_script
browser.execute_cdp_cmd
browser.execute_script
browser.file_detector
browser.file_detector_context
browser.find_element
browser.find_element_by_class_name
browser.find_element_by_css_selector
browser.find_element_by_id
browser.find_element_by_link_text
browser.find_element_by_name
browser.find_element_by_partial_link_text
browser.find_element_by_tag_name
browser.find_element_by_xpath
browser.find_elements
browser.find_elements_by_class_name
browser.find_elements_by_css_selector
browser.find_elements_by_id
browser.find_elements_by_link_text
browser.find_elements_by_name
browser.find_elements_by_partial_link_text
browser.find_elements_by_tag_name
browser.find_elements_by_xpath
browser.forward
browser.fullscreen_window
browser.get
browser.get_cookie
browser.get_cookies
browser.get_log
browser.get_network_conditions
browser.get_screenshot_as_base64
browser.get_screenshot_as_file
browser.get_screenshot_as_png
browser.get_window_position
browser.get_window_rect
browser.get_window_size
browser.implicitly_wait
browser.launch_app
browser.log_types
browser.maximize_window
browser.minimize_window
browser.mobile
browser.name
browser.orientation
browser.page_source
browser.quit
browser.refresh
browser.save_screenshot
browser.service
browser.session_id
browser.set_network_conditions
browser.set_page_load_timeout
browser.set_script_timeout
browser.set_window_position
browser.set_window_rect
browser.set_window_size
browser.start_client
browser.start_session
browser.stop_client
browser.switch_to
browser.switch_to_active_element
browser.switch_to_alert
browser.switch_to_default_content
browser.switch_to_frame
browser.switch_to_window
browser.title
browser.w3c
browser.window_handlesbrowser
todo
以下是一些其他使用技巧。
禁止加载图片和JS,可使用以下方法:
chrome_options = webdriver.ChromeOptions()
prefs={
'profile.default_content_setting_values': {
'images':2,
'javascript':2
}
}
chrome_options.add_experimental_option("prefs", prefs)
driver.switch_to.frame('ptlogin_iframe') # 切换框架页
driver.implicitly_wait(10) # 自动检测,如果10秒未成功则报错
# 通过文字定位元素
b.find_element_by_xpath("//[text()='点我']")
b.find_element_by_xpath("//*[contains(text(), '我')]")
想解压通过 gzip 压缩的请求返回数据可通过以下方法:
# 方法二,推荐
import gzip
# r 为 gzip 压缩的 bytes
gzip.decompress(r)
# ...
# 方法二
import zlib
# r 为 gzip 压缩的 bytes
zlib.decompress(r, 16+zlib.MAX_WBITS)
# ...
如果要监听浏览器的请求,可使用对 Selenium 三方封装 Selenium Wire:
# pip install selenium-wire
from seleniumwire import webdriver # Import from seleniumwire
# Create a new instance of the Chrome driver
driver = webdriver.Chrome()
# Go to the Google home page
driver.get('https://www.google.com')
# Access requests via the `requests` attribute
for request in driver.requests:
if request.response:
print(
request.url,
request.response.status_code,
request.response.headers['Content-Type']
)
'''
https://www.google.com/ 200 text/html; charset=...
https://www.google.com/images/branding/googlelo...
https://consent.google.com/status?continue=http...
https://www.google.com/images/branding/googlelo...
https://ssl.gstatic.com/gb/images/i2_2ec824b0.p...
https://www.google.com/gen_204?s=webaft&t=aft&a...
...
'''
更新时间:2022-04-19 14:22:26 标签:selenium python 测试