我们知道,在chrome浏览器中,做反爬不难,
driver = webdriver.Chrome(executable_path=r"C:\ProgramData\Anaconda3\chromedriver.exe")
# -----------------------------------------------修改chromedriver.exe的路径---------------------------
# 过网站检测,没加这句的话,账号密码登录时滑动验证码过不了,但二维码登录不受影响
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{"source": """Object.defineProperty(navigator, 'webdriver',
{get: () => undefined})"""})
甚至一句话就行 或者也可再搞一下user-agent
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'
}
driver.execute_cdp_cmd('Network.setUserAgentOverride', headers=headers, userAgent='Mozilla/5.0')
但是,在firefox和edge浏览器中,
driver = webdriver.Firefox(executable_path=r"C:\ProgramData\Anaconda3\geckodriver.exe")
Firefox和Edge没有execute_cdp_cmd方法!!!!只能通过execute_script()方法来实现,而这个只是相当于一个在控制台运行js代码的方法。
execute_cdp_cmd
是 Selenium WebDriver 提供的一种与浏览器的 Chrome DevTools Protocol(CDP)进行交互的方式。CDP是一组API,可以用于获取和操作Chrome浏览器中的各种信息和行为。
execute_cdp_cmd
可以让使用 Selenium 的开发人员直接在 Python 中发送 CDP 命令,并获取命令的执行结果。通过这种方式,我们可以通过编写 Python 代码来控制浏览器的行为,例如截屏或者更改浏览器的网络设置等。
与和execute_script()的区别:
execute_script
和execute_cdp_cmd
都是 Selenium WebDriver 提供的用于和浏览器进行交互的方法,但它们之间有一些区别:
工作原理不同:
execute_script
是通过向浏览器注入JavaScript脚本的方式来实现,在浏览器端使用 JavaScript 引擎执行脚本。而execute_cdp_cmd
是通过与浏览器的 Chrome DevTools Protocol 进行通信,向浏览器发送 HTTP 请求,并获取响应来实现的。功能不同:
execute_script
可以执行任何有效的 JavaScript 代码,包括对页面上元素的操作、DOM 操作、监听事件等。而execute_cdp_cmd
则主要用于执行与浏览器的低级交互,例如截屏、模拟网络请求等。使用场景不同:由于
execute_cdp_cmd
主要用于执行低级别的浏览器操作,因此在许多情况下,我们可能更倾向于使用更专业化的 CDP 库,而不是直接使用execute_cdp_cmd
。而execute_script
然后是处理浏览器中的 JavaScript 技术栈的强大工具,因此在许多情况下,我们会使用execute_script
来访问和操作页面元素。总之,
execute_script
和execute_cdp_cmd
都是 Selenium WebDriver 常用的工具,但它们具有不同的用途和使用场景。需要根据具体情况来选择适合的方法。
其实主要问题就是:
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": """Object.defineProperty(navigator, 'webdriver', { get: () => undefined})"""})
和
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
的区别是什么的问题,execute_cdp_cmd只要写一次就能实现真正的反反爬,而execute_script则需要经常性的设置webdriver为undifined才行!!!
而execute_cdp_cmd只能用在chrome浏览器上!!!所以要想在firefox和edge浏览器中实现相同的功能,就需要经常的设置webdriver为undifined!!!!
所以在firefoc和edge引擎下实现反爬的例子:
driver.get(url)
# driver.execute_script("")
driver.maximize_window()
driver.get(url)
# 最多等待5秒使页面加载进来,隐式等待
driver.implicitly_wait(5)
# 获取并点击右上角登录按钮
login = driver.find_element(by=By.ID, value='J-btn-login')
login.click()
driver.implicitly_wait(5)
# driver.execute_script(
# '''
# navigator.userAgent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'
# ''')
# driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined}); \
# window.navigator.chrome = {runtime: {}, loadTimes: function() {}}; \
# Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']}); \
# Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3, 4, 5]});")
# 账号密码登录
username_tag = driver.find_element(by=By.ID, value='J-userName')
username_tag.send_keys(conf.username)
password_tag = driver.find_element(by=By.ID, value='J-password')
password_tag.send_keys(conf.password)
login_now = driver.find_element(by=By.ID, value='J-login')
login_now.click()
time.sleep(2)
# 为了完成验证码的验证,把webdriver的设置写在这里才行!!!不可以写在刚进入get(url)的地方,要写在离过验证码近的地方!!!!
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
# 过滑动验证码
# while True:
picture_start = driver.find_element(by=By.ID, value='nc_1_n1z')
# 移动到相应的位置,并左键鼠标按住往右边拖
ActionChains(driver).move_to_element(picture_start).click_and_hold(picture_start).move_by_offset(300, 0).release().perform()
# 如果出现验证失败 需要刷新的话 再次来一遍
try:
time.sleep(1.5)
driver.find_element(by=By.XPATH, value='//*[@id="nc_1_refresh1"]').click() # 点击刷新
time.sleep(1)
picture_start = driver.find_element(by=By.ID, value='nc_1_n1z')
# 移动到相应的位置,并左键鼠标按住往右边拖
ActionChains(driver).move_to_element(picture_start).click_and_hold(picture_start).move_by_offset(300,
0).release().perform()
except:
pass
# 为了完成验证码的验证,把webdriver的设置写在这里才行!!!不可以写在刚进入get(url)的地方,要写在离过验证码近的地方!!!!
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
而firefox和edge引擎的定义是这样写的:
driver = webdriver.Firefox(executable_path=r"C:\ProgramData\Anaconda3\geckodriver.exe")
driver = webdriver.Edge(executable_path=r"C:\ProgramData\Anaconda3\msedgedriver.exe")