Python 爬虫利器 Selenium 从入门到进阶(下)

发表于:2024-1-19 09:22

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:编辑啊青    来源:今日头条

  鼠标的控制
  鼠标的控制都是封装在ActionChains类当中,常见的有以下几种:
  引入action_chains类
  from selenium.webdriver.common.action_chains import ActionChains
  # 右击
  ActionChains(driver).context_click(element).perform()
  # 双击
  ActionChains(driver).double_click(element).perform()
  # 拖放
  ActionChains(driver).drag_and_drop(Start, End).perform()
  # 悬停
  ActionChains(driver).move_to_element(Above).perform()
  # 按下
  ActionChains(driver).click_and_hold(leftclick).perform()
  # 执行指定的操作
  键盘的控制
  webdriver中的Keys()类,提供了几乎所有按键的方法,常用的如下
  # 删除键
  driver.find_element_by_id('xxx').send_keys(Keys.BACK_SPACE)
  # 空格键
  driver.find_element_by_id('xxx').send_keys(Keys.SPACE)
  # 回车键
  driver.find_element_by_id('xxx').send_keys(Keys.ENTER)
  # Ctrl + A 全选内容
  driver.find_element_by_id('xxx').send_keys(Keys.CONTROL, 'a')
  # Ctrl + C/V 复制/粘贴内容
  driver.find_element_by_id('xxx').send_keys(Keys.CONTROL, 'c')
  driver.find_element_by_id('xxx').send_keys(Keys.CONTROL, 'v')
  其他的一些键盘操作
  ·向上箭头:Keys.ARROW_UP
  · 向下箭头:Keys.ARROW_DOWN
  · 向左/向右箭头:Keys.ARROW_LEFT/Keys.ARROW_RIGHT
  · Shift键:Keys.SHIFT
  · F1键:Keys.F1
  元素的等待
  有显示等待和隐式等待两种。
  显示等待
  显示等待指的是设置一个超时时间,每隔一段时间去查看一下该元素是否存在,如果存在则执行后面的内容,要是超过了最长的等待时间,则抛出异常(TimeoutException),需要用到的是WebDriverWait()方法,同时配合until和not until方法。
  WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
  其中的参数:
  · timeout: 最长超时时间,默认以秒为单位
  · poll_frequency: 检测的时间间隔,默认是0.5s
  · ignored_exceptions: 指定忽略的异常,默认忽略的有NoSuchElementException这个异常
  我们来看下面的案例:
  driver = webdriver.Chrome()
  driver.get("http://somedomain/url_that_delays_loading")
  try:    
      element = WebDriverWait(driver, 10).until(           
          EC.presence_of_element_located((By.ID, "myDynamicElement")))
  finally:    
      driver.quit()
  上面的代码最多等待10秒,超时后就抛出异常,但是假设在等了3秒之后就找到了这个元素,那么也就不会多等下剩下的7秒钟时间,而是继续执行后续的代码。
  隐式等待
  主要使用的是implicitly_wait()来实现:
  browser = webdriver.Chrome(path)
  # 隐式等待3秒
  browser.implicitly_wait(3)
  获取Cookie
  Cookie是用来识别用户身份的关键,我们通常也是通过selenium先模拟登录网页获取Cookie,然后再通过requests携带Cookie来发送请求。
  webdriver提供了cookies的几种操作,我们挑选几个常用的来说明
  · get_cookies():以字典的形式返回当前会话中可见的cookie信息
  ·get_cookies(name): 返回cookie字典中指定的的cookie信息
  · add_cookie(cookie_dict): 将cookie添加到当前会话中
  下面看一个简单的示例代码:
  driver=webdriver.Chrome(executable_path="chromedriver.exe")
  driver.get(url=url)
  time.sleep(1)
  cookie_list=driver.get_cookies()
  cookies =";".join([item["name"] +"=" + item["value"] + "" for item in cookie_list])
  session=requests.session()
  headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36',
      'cookie': cookies
  }
  response=session.get(url=url,headers=headers)
  soup=BeautifulSoup(response.text,'lxml')
  调用JavaScript
  在webdriver当中可以使用execut_script()方法来实现JavaScript的执行,下面我们来看一个简单的例子。
  from selenium import webdriver
  import time
  bro=webdriver.Chrome(executable_path='./chromedriver')
  bro.get("https://www.baidu.com")
  # 执行js代码
  bro.execute_script('alert(10)')
  time.sleep(3)
  bro.close()
  除此之外,我们还可以通过selenium执行JavaScript来实现屏幕上下滚动
  from selenium import webdriver
  bro=webdriver.Chrome(executable_path='./chromedriver')
  bro.get("https://www.baidu.com")
  # 执行js代码
  bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
  selenium进阶
  selenium启动的浏览器,会非常容易的被检测出来,通常可以通过window.navigator.webdriver的值来查看,如果是true则说明是使用了selenium模拟浏览器,如果是undefined则通常会被认为是正常的浏览器。
  那么我们似乎可以执行下面这段代码来强行更改window.navigator.webdriver最后返回的值:
  driver.execute_script(
      'Object.defineProperties(navigator,{webdriver:{get:()=>false}})'
  )
  当然这种方法也有一定的缺陷,毕竟这段代码是在网页已经加载完毕之后才运行的,此时网页自身的JavaScript程序已经通过读取window.navigator.webdriver知道你使用的是模拟浏览器了。所以我们有两种办法来解决这个缺陷。
  ·在Chrome当中添加实验性功能参数
  代码如下:
  from selenium.webdriver import Chrome
  from selenium.webdriver import ChromeOptions
  option = ChromeOptions()
  option.add_experimental_option('excludeSwitches',['enable-automation'])
  driver=Chrome(options=option)
  ·调用chrome当中的开发工具协议的命令
  核心思想就是让Chrome浏览器在打开页面,还没有运行网页自带的JavaScript代码时,先来执行我们给定的代码,通过execute_cdp_cmd()方法:
  driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
      "source": """
          Object.defineProperty(navigator, 'webdriver', {
              get: () => undefined
          })
      """
  })
  当然为了更好隐藏指纹特征,我们可以将上面两种方法想结合
  from selenium import webdriver
  options = webdriver.ChromeOptions()
  options.add_experimental_option("excludeSwitches", ["enable-automation"])
  options.add_experimental_option('useAutomationExtension', False)
  driver = webdriver.Chrome(options=options, executable_path='./chromedriver')
  driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": """
      Object.defineProperty(navigator, 'webdriver', {
        get: () => undefined
      })
    """
  })
  driver.get(url)
  最后的最后,我们也可以通过运行stealth.min.js文件来实现隐藏selenium模拟浏览器的特征,这个文件之前是给puppeteer用的,使得其隐藏浏览器的指纹特征,而让Python使用时,需要先导入这份JS文件。
  import time
  from selenium.webdriver import Chrome
  option = webdriver.ChromeOptions()
  option.add_argument("--headless")
  # 无头浏览器需要添加user-agent来隐藏特征
  option.add_argument('user-agent=.....')
  driver = Chrome(options=option)
  driver.implicitly_wait(5)
  with open('stealth.min.js') as f:
      js = f.read()
  driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": js
  })
  driver.get(url)
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号