一、介绍今天主要介绍微博客户端登录时出现的四方手绘验证码,话不多说,看看验证码长什么样喜欢。二、思路1、由于微博上的手绘验证码只有四个格子,而每个格子之间都有有向线段连接,因此我们可以判断出四个格子的不同方向有24种验证码,我们对四个格子进行标注,结果如下:那么我们可以排列出24个不同的手绘验证码,分别是下面的24种。2、我们从微博客户端获取了24个手绘验证码最后需要进行模板匹配,所以滑动是通过全图匹配进行的。三、代码实现1、首先需要通过微博移动端(https://passport.weibo.cn/sig...)批量获取手绘验证码,但是这个验证码不一定出现,只有当账户有风险或者经常登录的时候才会出现。获取手绘验证码的代码如下:注意:发送用户名和密码前需要加载模拟浏览器的所有元素(用户名框、密码框),否则会报错#-*-编码:utf-8-*-从io导入BytesIO从PIL导入图像从selenium导入webdriver从selenium.webdriver.common.by导入Byfromselenium.common.exceptions从selenium.webdriver.support.ui导入TimeoutException从selenium.webdriver.support导入WebDriverWaitimportexpected_conditionsasECclassCrackWeiboSlide():def__init__(self):self.url="https://passport.weibo.cn/signin/login?entry=mweibo&r=https://m.weibo.cn/"self.browser=webdriver.Chrome(r"D:\chromedriver.exe")self.browser.maximize_window()self.wait=WebDriverWait(self.browser,5)def__del__(self):self.browser.close()def打开(self):#打开模拟浏览器self.browser.get(self.url)#获取用户名元素username=self.wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="loginName"]')))#获取密码框元素password=self.wait.uuntil(EC.presence_of_element_located((By.XPATH,'//*[@id="loginPassword"]')))#获取登录按钮元素submit=self.wait.until(EC.element_to_be_clickable((By.XPATH,'//*[@id="loginAction"]')))#提交数据并登录username.send_keys("15612345678")password.send_keys("xxxxxxxxxxxx")submit.click()defget_image(self,name="captcha.png"):try:#获取验证码imageelementimg=self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,"patt-shadow")))time.sleep(1)#获取验证码codeimagelocationlocationlocation=img.location#获取验证码图片的大小size=img.sizetop=location["y"]#upperbottom=location["y"]+size["height"]#lowerleft=location["x"]#Leftright=location["x"]+size["width"]#Rightprint("验证码位置:",left,top,right,bottom)#截图当前窗口截图=self.browser.get_screenshot_as_png()#读取截图screenshot=Image.open(BytesIO(screenshot))#截取九宫格图片验证码captcha=screenshot.crop((left,top,right,bottom))#将截取的九宫格验证码保存到指定位置captcha.save(name)print("微博登录验证码已保存!!!")returncaptchaexceptTimeoutException:print("没有验证码!!!")#回调打开模拟浏览器函数self.open()defmain(self):count=1whileTrue:#调用打开模拟浏览器函数self.open()#调用函数获取验证码图片self.get_image(str(count)+".png")count+=1if__name__=='__main__':crack=CrackWeiboSlide()crack.main()得到的24种手绘验证码,这些手绘验证码需要按照上面的数字命名。上图就是我们需要的模板,接下来我们就要遍历模板匹配2.模板匹配可以通过遍历手绘验证码模板来匹配selenium.webdriver.common.byimportByfromselenium.common.exceptionsimportTimeoutExceptionfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECclassCrackWeiboSlide():def__init__(self):self.url="https://passport.weibo.cn/signin/login?entry=mweibo&r=https://m.weibo.cn/"self.browser=webdriver.Chrome(r"D:\chromedriver.exe")self.browser.maximize_window()self.wait=WebDriverWait(self.browser,5)def__del__(self):self.browser.close()defopen(self):#打开模拟浏览器self.browser.get(self.url)#获取用户名元素username=self.wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="loginName"]')))#获取密码框元素password=self.wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="loginPassword"]')))#获取登录按钮元素submit=self.wait.until(EC.element_to_be_clickable((By.XPATH,'//*[@id="loginAction"]')))#提交数据登录username.send_keys("15612345678")password.send_keys("xxxxxxxxxxxx")submit.click()defget_image(self,name="captcha.png"):try:#获取验证码图像元素img=self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,"patt-shadow")))time.sleep(1)#获取验证码图片位置location=img.location#获取验证码图片大小size=img.sizetop=location["y"]#Topbottom=location["y"]+size["height"]#Bottomleft=location["x"]#Leftright=location["x"]+size["width"]#Rightprint("验证码位置:",left,top,right,bottom)#当前窗口截图screenshot=self.browser.get_screenshot_as_png()#读取截图screenshot=Image.open(BytesIO(screenshot))#截取九宫格图片验证码captcha=screenshot.crop((left,top,right,bottom))#将截取的九宫格验证码保存到指定位置captcha.save(name)print("微博登录验证码已保存!!!")#返回微博手机端验证码图片returncaptchaexceptTimeoutException:print("没有验证码!!")#回调打开模拟浏览器功能self.open()defis_pixel_equal(self,image,template,i,j):#取出两张图片的像素pixel1=image.load()[i,j]#手机客户端获取的验证码pixel2=template.load()[i,j]#模板文件中的验证码threshold=20#thresholdpix_r=abs(pixel1[0]-pixel2[0])#Rpix_g=abs(pixel1[1]-pixel2[1])#Gpix_b=abs(pixel1[2]-pixel2[2])#Bif(pix_r
