说在后面:次要应用 Python 的 Selenium 库和对应的 WebDriver(例如 ChromeDriver),通过模仿鼠标操作实现。
代码示例
接下来间接上干货:
- 应用 Selenium 启动浏览器,并关上验证码页面。
from selenium import webdriverdriver = 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 Imagefrom io import BytesIOslider = 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 ActionChainsslider_width = slider.size['width']distance = x + slider_width / 2actions = ActionChains(driver)actions.click_and_hold(slider).perform()actions.move_by_offset(distance, 0).perform()actions.release().perform()
整体的代码的话,就是:
import requestsfrom PIL import Imagefrom io import BytesIOimport numpy as npimport cv2from selenium import webdriverfrom selenium.webdriver.common.action_chains import ActionChainsdriver = 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,这方面要重点思考。)
其实最不便的是找个现成的验证码代码间接应用,比方顶象的滑动验证码,能够间接收费应用。