精通Python爬虫:如何应对各种验证码? 在进行爬取网站数据时,我们难免会遇到各种验证码,如数字、文字、滑块、倒立文字、拖动验证等等。这些验证码是为了防止被机器人爬取而设置的安全措施。本文将介绍如何使用Python解决各种验证码问题。 1. 数字验证码 数字验证码是最简单的一种验证码,一般由0-9的数字组成。我们可以使用Python的Pillow库,通过图像处理技术识别出验证码内容。以下是一个示例代码: ```python from PIL import Image import pytesseract img = Image.open('captcha.png') img = img.convert('L') text = pytesseract.image_to_string(img, config='digits') print(text) ``` 这段代码中,我们首先使用Pillow库打开验证码图片,然后将图片转为灰度图像,最后使用pytesseract库的image_to_string方法,将图像中的数字转为文本。config参数指定识别数字文本,如果验证码中包含字母,我们可以设置为'letters'。 2. 文字验证码 文字验证码由大小写字母和数字组成,一般较为复杂。我们可以使用CNN(卷积神经网络)模型进行训练,从而实现自动识别。以下是一个示例代码: ```python import tensorflow as tf import numpy as np from PIL import Image # 加载已训练的模型 model = tf.keras.models.load_model('captcha_model.h5') # 预处理验证码图片 def preprocess_image(image_path): image = Image.open(image_path).convert('RGB') image = np.array(image) image = tf.image.resize(image, [150, 300]) image /= 255.0 return np.expand_dims(image, axis=0) # 预测验证码 def predict_captcha(image_path): image = preprocess_image(image_path) pred = model.predict(image) return ''.join([chr(np.argmax(x)+97) for x in pred[0]]) # 测试 print(predict_captcha('captcha.png')) ``` 这段代码中,我们首先加载了已经训练好的CNN模型。然后对验证码图片进行预处理,缩放到指定的大小,并将像素值归一化。最后使用模型的predict方法进行预测,将预测结果转为文本。 3. 滑块验证码 滑块验证码是现在比较常见的一种验证码,用户需要通过拖动滑块,将滑块移动到指定位置,才能通过验证。我们可以使用selenium库模拟用户操作,并通过比较滑块前后背景图像的相似度,确定滑块的位置。以下是一个示例代码: ```python from selenium import webdriver from PIL import Image import time import numpy as np # 打开浏览器 driver = webdriver.Chrome() driver.get('https://www.google.com/recaptcha/api2/demo') # 等待验证码加载 while True: if driver.execute_script('return document.readyState') == 'complete': break time.sleep(1) # 获取滑块和背景图片链接 slider_url = driver.find_element_by_css_selector('.rc-slider').get_attribute('src') bg_url = driver.find_element_by_css_selector('.rc-imageselect-target').get_attribute('src') # 下载图片 def download_image(url): driver.get(url) image = driver.find_element_by_tag_name('img') src = image.get_attribute('src') return Image.open(requests.get(src, stream=True).raw) slider_image = download_image(slider_url) bg_image = download_image(bg_url) # 计算滑块位置 def get_position(): slider = np.array(slider_image.convert('L')) bg = np.array(bg_image.convert('L')) threshold = 100 diff = np.abs(slider-bg) for i in range(diff.shape[0]): if np.sum(diff[i,:]) > threshold: return i # 模拟滑动操作 def slide_to(position): slider = driver.find_element_by_css_selector('.rc-slider-handle') actions = webdriver.ActionChains(driver) actions.click_and_hold(slider).perform() for _ in range(position): actions.move_by_offset(1, 0).perform() actions.release().perform() # 执行验证码识别 position = get_position() print('滑块位置:', position) slide_to(position) ``` 这段代码中,我们首先使用selenium库打开一个recaptcha演示网页,并等待验证码加载完成。然后获取滑块和背景图片的链接,并进行下载。最后通过比较滑块和背景图像的相似度,确定滑块位置,模拟滑动操作,完成验证码识别。 4. 倒立文字验证码 倒立文字验证码是为了防止机器人爬取而设置的一种复杂验证码,文字呈倒立状态,一般需要翻转或旋转才能正确识别。我们可以使用图像处理技术将文本翻转或旋转至正常状态,再进行识别。以下是一个示例代码: ```python from PIL import Image import pytesseract # 加载已训练的模型 model = load_model('captcha_model.h5') # 预处理验证码图片 def preprocess_image(image_path): image = Image.open(image_path).convert('L') image = image.resize((image.width*5, image.height*5)) image = ImageOps.invert(image) return np.array(image) # 反转倒立文本 def invert_text(img): inv_img = ImageOps.invert(img) text_img = Image.new('L', inv_img.size, 255) text_img.paste(inv_img, (0, inv_img.height//2)) angle = pytesseract.image_to_osd(text_img)['rotate'] return text_img.rotate(-angle, resample=Image.BICUBIC, fillcolor=255) # 预测验证码 def predict_captcha(image_path): image = preprocess_image(image_path) text_img = invert_text(Image.fromarray(image)) text = pytesseract.image_to_string(text_img) return text # 测试 print(predict_captcha('captcha.png')) ``` 这段代码中,我们首先加载已经训练好的CNN模型。然后对验证码图片进行预处理,将图像缩放,并将像素值反转。接着使用pytesseract库的image_to_osd方法,获取倒立文本的旋转角度。最后将文本图像旋转至正常状态,使用pytesseract库的image_to_string方法,将文本转为字符串。