用python写一爬虫,需要模拟登陆,并且有数字验证码。通过selenium+pytesseract+PIL可以实现验证码识别并登陆。三大步:
- 用selenium截屏,此时截取的是整个页面的
- 用PIL库中的Image库,从刚才页面截屏中,通过crop()方法截取 出来验证码图片,然后进行灰度和二值化处理
- 用pytesseract库中的image_to_srting()方法,将图片转化为字符串。切割之后,转为数字。
具体实现的代码如下,需要先安装一下相应的库哦。
# coding=utf-8 from selenium import webdriver import time from selenium.webdriver.firefox.options import Options as FOptions import datetime import pymysql import json import numpy as np from PIL import Image, ImageEnhance import pytesseract options = FOptions() obj = webdriver.Firefox(executable_path="geckodriver.exe", firefox_options=options) obj.get('https://qcar.apiins.com/qcar/reLogin.do') time.sleep(1) obj.switch_to.alert.accept() obj.find_element_by_name('usercode').send_keys('***********') obj.find_element_by_name('passwd').send_keys('********') """ 用selenium截图,先截整个页面,然后定位验证码图片,截取出来验证码图片 """ obj.save_screenshot('hebao_login.png') codeEelement = obj.find_element_by_id('VerifCode') print('验证码图片',codeEelement,type(codeEelement)) imgSize = codeEelement.size # 获取验证码图片的大小 print('图片大小',imgSize,type(imgSize)) imgLocation = codeEelement.location # 获取验证码元素坐标 print('图片位置',imgLocation,type(imgLocation)) rangle = (int(imgLocation['x']), int(imgLocation['y']), int(imgLocation['x'] + imgSize['width']),int(imgLocation['y'] + imgSize['height'])) # 计算验证码整体坐标 print(rangle) login = Image.open('hebao_login.png').convert('RGB') """ 截取下来验证码图片,并且进行灰度转化,二值化处理 """ loginImg = login.crop(rangle) # 截取验证码图片 loginImg.show() loginImg = loginImg.convert("L")#convert()方法传入参数L,将图片转化为灰度图像 loginImg.show() loginImg = np.asarray(loginImg) loginImg = (loginImg > 100) * 255 loginImg = Image.fromarray(loginImg).convert('RGB') sharpness = ImageEnhance.Contrast(loginImg) loginImg = sharpness.enhance(3.0) loginImg = loginImg.resize((300, 100)) loginImg.show() """ 将图片转化为文本字符串,切割之后,转化为数字进行计算 """ text = pytesseract.image_to_string(loginImg, lang='ytbx').strip().replace(' ', '') print(text) num = int(text.split('+?=')[1]) - int(text.split('+?=')[0]) print(num) obj.find_element_by_name('checkCode').send_keys(str(num)) obj.find_element_by_xpath('/html/body/form/div[2]/div/ul/li[5]/input').click() time.sleep(1)