selenium

https://blog.csdn.net/weixin_44110998/article/details/103185785   # selenium   学习

window.navigator.webdriver     #  规避检测

 

窗口切换

driver.get("https://seleniumhq.github.io")

driver.window_handle   # 获取所有的窗口id

driver.find_element(By.LINK_TEXT, "new window").click()  # 点击新连接,新打开一个窗口页面

driver.switch_to.window(driver.window_handle[-1])     # 切换到了新打开的窗口页面

 

#隐式等待:在查找所有元素时,如果尚未被加载,则等10秒 driver.implicitly_wait(10)

 

通过它我们可以让代码控制浏览器,从而进行数据爬取,尤其在以下两个地方该模块的作用更加强大:

  1. 获取整张页面的数据,对有的页面来说前后端分离的API接口太难找了,使用requests模块根本找不到发送加载数据的接口
  2. 进行自动登录

pip3 install selenium

下载浏览器驱动程序:

  • http://chromedriver.storage.googleapis.com/index.html
    查看驱动和浏览器版本的映射关系:
  • http://blog.csdn.net/huilan_same/article/details/51896672

 

   如果是MAC平台,解压到如下路径,win平台解压到任意位置皆可:

/usr/local/bin

 由于我们使用的是chorme浏览器,所以只需要实例化出其操纵对象即可:

from selenium import webdriver driver = webdriver.Chrome()

  以后的操纵都是操纵该实例对象,如果你使用其他版本浏览器,请自行下载驱动,支持的浏览器如下:

driver = webdriver.Firefox() driver = webdriver.Edge() driver = webdriver.PhantomJS() driver = webdriver.Safari()

1.基本使用

from selenium

import webdriver

import time

# 载入驱动

driver = webdriver.Chrome(r"./chromedriver.exe")

# 打开百度页面

driver.get("https://www.baidu.com")

# 找到搜索框,输入博客园

driver.find_element_by_id("kw").send_keys("博客园") time.sleep(2) driver.find_element_by_id('su').click() time.sleep(2)

# 关闭浏览器

driver.quit()

 

2.元素定位

driver.find_element_by_id()

driver.find_element_by_name()

driver.find_element_by_class_name()

driver.find_element_by_tag_name()

driver.find_element_by_link_text()

driver.find_element_by_partial_link_text()

driver.find_element_by_xpath()

driver.find_element_by_css_selector()

3 ifarme定位

 

对于webdriver来说,它拥有一层作用域。

 

   默认是在顶级作用域中,如果出现了ifarme标签,则必须切换到ifarme标签的作用域才能查找其里面的元素。

 

   如下,想查找其中的button

<div id="modal">

  <iframe id="buttonframe"name="myframe"src="https://seleniumhq.github.io">

    <button>Click here</button>

  </iframe>

</div>

 如果直接获取button则不会生效,因为目前作用域是外部的html标签中,不能获取内部iframe的作用域:

 正确的方法是找到ifarme标签,对其进行切换作用域的操作:

# 存储网页元素

iframe = driver.find_element(By.CSS_SELECTOR, "#modal > iframe")

# 切换到选择的

iframe driver.switch_to.frame(iframe)

# 单击按钮

driver.find_element(By.TAG_NAME, 'button').click()

如果您的frameiframe具有idname属性,则可以使用该属性。如果名称或 id 在页面上不是唯一的, 那么将切换到找到的第一个。

 还可以通过索引值进行切换:

# 切换到第 2 个框架
driver.switch_to.frame(1)
退出当前iframe的作用域,使用以下代码:
driver.switch_to.default_content()
 
 
4.交互相关

 我们可以与浏览器BOM或者element进行交互。

   如找到搜索框,使用send_keys()即可输入内容,clear()即可清空内容。

   再比如找到button使用click()即可触发单击事件。

      release().perform()  松开鼠标按键 与动作链配合

   更多方法请参照官方文档,截图也在其中:

https://www.selenium.dev/documentation/zh-cn/webdriver/browser_manipulation/

5. 动作链

 如果碰到滑动验证的操作,则需要使用动作链进行。

   上述的交互中,如send_keys()click()都是一次性完成的,如果是非一次性的操作如拖拽,滑动的就可以通过动作链完成。

   动作链的官方文档,包括获取当前元素的大小,配合截图使用有奇效,举个例子,截图到当前的验证码页面,然后使用第三方打码工具进行解析验证码:

https://www.selenium.dev/documentation/zh-cn/support_packages/mouse_and_keyboard_actions_in_detail/

 

from selenium import webdriver

from time import sleep

#导入动作链对应的类

from selenium.webdriver

import ActionChains

bro = webdriver.Chrome(executable_path='./chromedriver')

bro.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')

#如果定位的标签是存在于iframe标签之中的则必须通过如下操作在进行标签定位

bro.switch_to.frame('iframeResult')

#切换浏览器标签定位的作用域

div = bro.find_element_by_id('draggable')

#动作链

action = ActionChains(bro)

#点击长按指定的标签

action.click_and_hold(div)

for i in range(5):

  #perform()立即执行动作链操作

  #move_by_offset(x,y):x水平方向 y竖直方向

  action.move_by_offset(17,0).perform() sleep(0.5)

  #释放动作链

  action.release()

  bro.quit()

 

6. 执行脚本

 如果webdriver实例中没有实现某些方法,则可以通过执行Js代码来完成,比如下拉滑动条:

from selenium import webdriver

driver = webdriver.Chrome(r"./chromedriver.exe")

driver.get('https://www.jd.com/')

# 执行脚本:滑动整个页面

driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')

7. 动态数据

  上面提到过,如果使用requets模块访问某一url却没有拿到想要的数据,那么很可能是前后端分离通过RESTful APIs进行数据交互。

   这个时候我们可以使用selenium模块来对同一url发起请求,由于是浏览器打开,所有的RESTFUL API都会进行请求,然后直接通过属性page_source解析返回的源码数据:

from selenium import webdriver

from lxml import etree

driver=webdriver.Chrome(r"./chromedriver.exe",)

driver.get('https://www.baidu.com/')

source_code = driver.page_source   # 获取网页源代码

# 直接获取百度的图片地址

root = etree.HTML(source_code,parser=etree.HTMLParser())

driver.close()

img_src = "http:" + root.xpath(r"//*[@id='s_lg_img_new']")[0].attrib.get("src")

print(img_src)

 

11. 异常处理

屏蔽掉所有可能出现的异常:

from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException,NoSuchFrameException

try:
    browser=webdriver.Chrome()
    browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
    browser.switch_to.frame('iframssseResult')

except TimeoutException as e:
    print(e)
except NoSuchFrameException as e:
    print(e)
finally:
    browser.close()

12 无头操作

每次使用selenium时都会打开一个浏览器,能不能有什么办法让他隐藏界面呢?

   指定参数即可,这种没有界面的浏览也可以称其为无头浏览器:


from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 设置配置项chrome_options = Options()
chrome_options.add_argument('--headless')
# 指定配置driver = webdriver.Chrome(executable_path='./chromedriver.exe',chrome_options=chrome_options)
driver.get("http://www.baidu.com")
driver.close()

 

13 规避检测

window.navigator.webdriver   检测

 可能有的门户网站已经对selenium做出了检测,如果检测到是该脚本执行可能不允许你访问API,此时就可以通过伪造信息达到潜行的效果。

   将selenium伪装成人为操作:

#实现规避检测from selenium.webdriver import ChromeOptions#实现规避检测option = ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) # 指定配置driver = webdriver.Chrome(executable_path='./chromedriver.exe',options=option)driver.get("http://www.baidu.com") driver.close()

 

  屏蔽掉所有可能出现的异常:

posted on 2021-03-08 22:16  Plyc  阅读(69)  评论(0编辑  收藏  举报

导航