说在后面: 次要应用 Python 的 Selenium 库和对应的 WebDriver(例如 ChromeDriver),通过模仿鼠标操作实现。
代码示例
接下来间接上干货:
- 应用 Selenium 启动浏览器,并关上验证码页面。
from selenium import webdriver
driver = webdriver.Chrome() # 应用 Chrome 浏览器
driver.get('https://example.com/captcha') # 关上验证码页面
- 切换到蕴含验证码的 iframe 中。
iframe = driver.find_element_by_xpath('//iframe[@id="captcha-iframe"]')
driver.switch_to.frame(iframe)
- 找到验证码的滑块和背景图片,并应用 Pillow 库加载图片。
from PIL import Image
from io import BytesIO
slider = driver.find_element_by_xpath('//div[@class="slider"]')
slider_img = slider.find_element_by_xpath('.//img').get_attribute('src')
bg = driver.find_element_by_xpath('//div[@class="bg"]')
bg_img = bg.find_element_by_xpath('.//img').get_attribute('src')
bg_image = Image.open(BytesIO(requests.get(bg_img).content))
slider_image = Image.open(BytesIO(requests.get(slider_img).content))
- 应用图像处理库(例如 OpenCV)找到滑块在背景图片中的地位。
import cv2
# 把 PIL 图像转换为 OpenCV 图像
bg_cv = cv2.cvtColor(np.array(bg_image), cv2.COLOR_RGB2BGR)
slider_cv = cv2.cvtColor(np.array(slider_image), cv2.COLOR_RGB2BGR)
# 应用模板匹配算法找到滑块在背景图片中的地位
result = cv2.matchTemplate(bg_cv, slider_cv, cv2.TM_CCOEFF_NORMED)
y, x = np.unravel_index(result.argmax(), result.shape)
- 计算滑块须要挪动的间隔,并应用 Selenium 执行滑动操作。
from selenium.webdriver.common.action_chains import ActionChains
slider_width = slider.size['width']
distance = x + slider_width / 2
actions = ActionChains(driver)
actions.click_and_hold(slider).perform()
actions.move_by_offset(distance, 0).perform()
actions.release().perform()
整体的代码的话,就是:
import requests
from PIL import Image
from io import BytesIO
import numpy as np
import cv2
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
driver.get('https://example.com/captcha')
iframe = driver.find_element_by_xpath('//iframe[@id="captcha-iframe"]')
driver.switch_to.frame(iframe)
slider = driver.find_element_by_xpath('//div[@class="slider"]')
slider_img = slider.find_element_by_xpath('.//img').get_attribute('src')
bg = driver.find_element_by_xpath('//div[@class="bg"]')
bg_img = bg.find_element_by_xpath('.//img').get_attribute('src')
bg_image = Image.open(BytesIO(requests.get(bg_img).content))
slider_image = Image.open(BytesIO(requests.get(slider_img).content))
bg_cv = cv2.cvtColor(np.array(bg_image), cv2.COLOR_RGB2BGR)
slider_cv = cv2.cvtColor(np.array(slider_image), cv2.COLOR_RGB2BGR)
result = cv2.matchTemplate
注意事项
在理论利用过程中,要留神:
1. 要看本人网站具体情况定位和提取验证码的 HTML 构造和 CSS 款式。
2. 要依据本人的需要退出发爬措施,比方图片大小、地位、色彩等的变动。(这个比拟重要,因为如果只是一般的验证码,那么安全性其实不能失去很大的保障,而且当初黑灰产的工具很多,不多方防备的话,就相当于只是修了一个“褴褛的门”)
3. 代码中用到了第三方库(如 Pillow、OpenCV)和模仿鼠标操作,须要确保在非法和可控的状况下应用。(合规问题不必具体说了,如果是本人做的小程序,不上架的话,能够不必太思考这方面问题,然而如果须要上架,尤其是 App Sotre,这方面要重点思考。)
其实最不便的是找个现成的验证码代码间接应用,比方顶象的滑动验证码,能够间接收费应用。