19. 调用JavaScript代码
虽然WebDriver提供了操作浏览器的前进和后退方法,但对于浏览器滚动条并没有提供相应的操作方法。在这种情况下,就可以借助JavaScript来控制浏览器的滚动条。WebDriver提供了execute_script()
方法来执行JavaScript
代码。
用于调整浏览器滚动条位置的JavaScript代码如下:
<!-- window.scrollTo(左边距,上边距); --> window.scrollTo(0,450);
window.scrollTo()
方法用于设置浏览器窗口滚动条的水平和垂直位置。方法的第一个参数表示水平的左间距,第二个参数表示垂直的上边距。其代码如下:
from selenium import webdriver from time import sleep #1.访问百度 driver=webdriver.Firefox(executable_path ="F:\GeckoDriver\geckodriver") driver.get("http://www.baidu.com") #2.搜索 driver.find_element_by_id("kw").send_keys("selenium") driver.find_element_by_id("su").click() #3.休眠2s目的是获得服务器的响应内容,如果不使用休眠可能报错 sleep(2) #4.通过javascript设置浏览器窗口的滚动条位置 js="window.scrollTo(100,450);" driver.execute_script(js) sleep(3) driver.close()
通过浏览器打开百度进行搜索,并且提前通过set_window_size()
方法将浏览器窗口设置为固定宽高显示,目的是让窗口出现水平和垂直滚动条。然后通过execute_script()
方法执行JavaScripts代码来移动滚动条的位置。
滚动条上下左右滚动代码演示
from selenium import webdriver from time import sleep driver=webdriver.Firefox(executable_path ="F:\GeckoDriver\geckodriver") driver.set_window_size(400,400) driver.get("https://www.baidu.com") #2.搜索 # driver.find_element_by_id("kw").send_keys("selenium") # driver.find_element_by_id("su").click() #3.休眠2s目的是获得服务器的响应内容,如果不使用休眠可能报错 sleep(10) #4 滚动左右滚动条---向右 js2 = "var q=document.documentElement.scrollLeft=10000" driver.execute_script(js2) sleep(15) #5 滚动左右滚动条---向左 js3 = "var q=document.documentElement.scrollLeft=0" driver.execute_script(js3) sleep(15) #6 拖动到滚动条底部---向下 js = "var q=document.documentElement.scrollTop=10000" driver.execute_script(js) sleep(15) #7 拖动到滚动条底部---向上 js = "var q=document.documentElement.scrollTop=0" driver.execute_script(js) sleep(15) driver.close()
20. 窗口截图
自动化用例是由程序去执行的,因此有时候打印的错误信息并不十分明确。如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因。WebDriver提供了截图函数get_screenshot_as_file()
来截取当前窗口。
截屏方法:
方法 | 说明 |
get_screenshot_as_file(self, filename) | 用于截取当前窗口,并把图片保存到本地 |
from selenium import webdriver from time import sleep driver =webdriver.Firefox(executable_path ="F:\GeckoDriver\geckodriver") driver.get('http://www.baidu.com') driver.find_element_by_id('kw').send_keys('selenium') driver.find_element_by_id('su').click() sleep(2) #1.截取当前窗口,并指定截图图片的保存位置 driver.get_screenshot_as_file("D:\\baidu_img.jpg") driver.quit()
21. 关闭浏览器
在前面的例子中我们一直使用quit()方法,其含义为退出相关的驱动程序和关闭所有窗口。除此之外,WebDriver还提供了close()方法,用来关闭当前窗口。例多窗口的处理,在用例执行的过程中打开了多个窗口,我们想要关闭其中的某个窗口,这时就要用到close()方法进行关闭了。
方法 | 说明 |
close() | 关闭单个窗口 |
quit() | 关闭所有窗口 |
22. 封装
将各种方式获取元素的进行封装,以类似 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")
23. selenium 和 requests 结合
网页渲染后,单纯的 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()
另外,上述登录验证码问题:
- 滑动验证,可以 Selenium 模拟
- 滑动距离,图像梯度算法可判断
- 图文验证,可以 Python AI 库识别
24. 禁止加载图片和JS
禁止加载图片和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(), '我')]")
25. 解压 gzip
想解压通过 gzip 压缩的请求返回数据可通过以下方法:
# 方法二,推荐 import gzip # r 为 gzip 压缩的 bytes gzip.decompress(r) # ... # 方法二 import zlib # r 为 gzip 压缩的 bytes zlib.decompress(r, 16+zlib.MAX_WBITS) # ...
26. 监听请求
如果要监听浏览器的请求,可使用对 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... ... '''
✈参考阅读:
https://www.gairuo.com/p/python-selenium
https://selenium-python.readthedocs.io/
https://blog.csdn.net/weixin_36279318/article/details/79475388
https://zhuanlan.zhihu.com/p/111859925
http://www.selenium.org.cn/1694.html