爬虫验证码:破解【点击旋转验证码】 蔚落 2022-02-13 11:13 1174阅读 0赞 **这里破解某某动漫的点击翻转验证码为例:**![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDU3NjAxMA_size_16_color_FFFFFF_t_70] 分析页面的源码发现,这些翻转的图片,我们可以下载下来,既然可以获取到这些图片,那么这个的**破解思路**为: 1. **获取1000张样本集合:** 用selenium访问,通过截屏,以及切片,一次获取四张图片,然后点击"换一组",依次循环1000次 2. **对获取的图片进行去重:** 通过图片的rbg总值来去重,rgb总值相差3000以为,基本认为这是同一张图片,就只保留一张。 3. **人为手动给去重的图片进行调整。** 4. **通过selenium来模拟登录,输入账号和密码** 5. **截屏,截取验证码图片** 6. **翻转每张验证码,记录翻转次数,通过和样本基本的每张图片的rgb进行一一比较,如果每个像素的rgb都小于100,那么这个翻转后的图片就是正确的位置,返回翻转次数。** 7. **依次翻转,记录各个图片需要翻转的次数** 8. **点击对应图片的元素,进行翻转** 9. **点击提交按钮,进行登录** 10. **判断是否登录成功** **获取1000张样本集的代码:** from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from PIL import Image import random from io import BytesIO import time class Crack(object): def __init__(self, start_number, count): self.login_url = "http://www.1kkk.com/" self.start_number = start_number self.count = count self.chrome_options = webdriver.ChromeOptions() self.chrome_options.add_argument("--healess") self.browser = webdriver.Chrome() self.browser.maximize_window() self.wait = WebDriverWait(self.browser, 30) def login(self): """ 输入账号,密码 :return:None """ self.browser.get(self.login_url) self.browser.find_element_by_class_name("header-avatar").click() # 获取所有图片 for num in range(self.start_number, self.start_number+self.count): self.image_png(num) self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "rotate-refresh"))).click() time.sleep(0.5) def save_screen_png(self): """ 获取网页截图 :return: 截图对象 """ self.wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, "rotate-background"))) screen_image = self.browser.get_screenshot_as_png() screenshot = Image.open(BytesIO(screen_image)) screenshot.save("screenshot{}.png".format(random.randint(1, 5))) return screenshot def image_png(self, num): """ 通过获取网页截图,然后进行切片,返回四张图片 :return: """ screenshot = self.save_screen_png() images = [] for num_2 in range(1, 5): # 依次获取5张图片,存入iamges列表中 images.append(self.get_image_position(screenshot, num, num_2)) # 获取整体四张图片的坐标 # 进行切片 def get_image_position(self, screenshot, number, number_2): """ 获取四张图片的下标 :return: left, top, right, bottom """ image = self.wait.until(EC.presence_of_element_located((By.XPATH, "//div[@class='rotate-background'][{}]".format(number_2)))) location = image.location size = image.size top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[ 'width'] image = screenshot.crop((left, top, right, bottom)) image.save("./static/total_images/image{}_{}.png".format(number, number_2)) return image def __del__(self): self.browser.quit() def download(start_number, count): """ 初始化登录类,下载图片 :param start_number:开启位置 :param count: 数量 :return: """ c = Crack(start_number, count) c.login() del c def main(): download(1, 1000) if __name__ == '__main__': main() **图片去重的代码:** from PIL import Image import os import gevent from gevent import monkey monkey.patch_all() # 图片数量 gCount = 0 # 列表,用来保存rgb rgb_dif_list = [] # 当前保存图片的名称 gNumber = 0 def sum_rgb(image): """ 计算rgb的值 :param images: 图片 :return: rgb的值 """ num = 0 for i in range(image.size[0]): for y in range(image.size[1]): pixel = image.load()[i, y] num = num + image.load()[i, y][0] + image.load()[i, y][1] + image.load()[i, y][2] return num def check_have_in(num): """ 通过rgb的总值,来判断是否已经存在列表 :param num: Ture or False :return: """ global rgb_dif_list if num in rgb_dif_list: # 如果存在,就得删除 return True else: # 否则就将rgb存入列表中,更改名字,并返回False return False def delete(image_url): """ 删除图片 :param image_url: 图片的url :return: """ print("删除图片:", image_url) os.remove(image_url) def start_check(start_number, count): global rgb_dif_list global gCount global gNumber images_url = "./static/total_images/{}" save_url = "./static/images/{}" for number_1 in range(start_number, start_number + count): for number_2 in range(1, 5): image_url = images_url.format("image{}_{}.png".format(number_1, number_2)) if os.path.isfile(image_url): image = Image.open(image_url) # 通过元素的rgb三个值相加的总数,通过列表保存,如果在列表中存在就添加,否则就删除 rgb_num = sum_rgb(image) print("image{}_{}.png".format(number_1, number_2), rgb_num) # 判断该图片的rgb是否已经存在列表中 if rgb_num > 4000000: continue for num in range(rgb_num-3000, rgb_num+3000): check_result = check_have_in(num) # 判断结果,做响应处理 if check_result: # 存在情况,退出 break else: rgb_dif_list.append(rgb_num) gCount += 1 # 不存在情况,更改名字 gNumber += 1 image.save(save_url.format("images{}.png".format(gNumber))) if start_number+count == 501: print("剩余图片总数为", gCount) def main(): gevent.joinall([ gevent.spawn(start_check, 1, 100), gevent.spawn(start_check, 101, 100), gevent.spawn(start_check, 201, 100), gevent.spawn(start_check, 301, 100), gevent.spawn(start_check, 401, 100), ]) # start_check(1, 10) if __name__ == "__main__": main() **验证码破解:** from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException import time import os from PIL import Image from io import BytesIO class Crack(object): def __init__(self): self.login_url = "http://www.1kkk.com/" # self.chrome_options = webdriver.ChromeOptions() # self.chrome_options.add_argument("--healess") self.browser = webdriver.Chrome() self.browser.maximize_window() self.wait = WebDriverWait(self.browser, 10) self.browser.get(self.login_url) time.sleep(2) def login(self): """ 输入账号,密码 :return:None """ try: self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, "header-avatar"))).click() except TimeoutException: self.browser.refresh() self.login() return # self.browser.find_element_by_class_name("header-avatar").click() name_page = self.browser.find_element_by_name("txt_name") name_page.send_keys("18218299414") password_page = self.browser.find_element_by_name("txt_password") password_page.send_keys("shao0812") true_or_false = True while true_or_false: true_or_false = False # 获取四张需要旋转的图片 images = self.image_png() # 获取整体四张图片的几次 turn_num_list = [] for image in images: turn_num_list.append(self.image_turn_num(image)) # print(turn_num_list) for i in turn_num_list: if i == 5: self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'rotate-refresh'))).click() time.sleep(3) true_or_false = True # 根据上面得到的旋转次数点击图片 self.click_image(turn_num_list) # 结果正确,点击登录按钮 self.click_submit() # todo: 如果旋转出问题,就得重新.来 # try: if self.browser.find_element_by_css_selector(".tip.color-main").text == "请点击下方图片,旋转至正确方向~": # 如果登录不成功,将重新刷新页面登录 self.browser.refresh() self.login() time.sleep(5) def click_image(self, turn_num_list): """ 通过算出来的点击次数,来点击图片 :param turn_num_list: 四张图需要点击的次数 :return: None """ for i in range(0, len(turn_num_list)): if turn_num_list[i] == 0: continue image = self.wait.until( EC.presence_of_element_located((By.XPATH, "//div[@class='rotate-background'][{}]".format(i+1)))) for _ in range(turn_num_list[i]): image.click() time.sleep(1) def save_screen_png(self): """ 获取网页截图 :return: 截图对象 """ screen_image = self.browser.get_screenshot_as_png() screenshot = Image.open(BytesIO(screen_image)) # screenshot.save("screenshot.png") return screenshot def image_png(self): """ 通过获取网页截图,然后进行切片,返回四张图片 :return: """ screenshot = self.save_screen_png() images = [] for num in range(1, 5): # 依次获取4张图片,存入iamges列表中 images.append(self.get_image(screenshot, num)) return images def get_image(self, screenshot, number): """ 获取四张图片的下标 :return: left, top, right, bottom """ image = self.wait.until(EC.presence_of_element_located((By.XPATH, "//div[@class='rotate-background'][{}]".format(number)))) location = image.location size = image.size top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[ 'width'] image = screenshot.crop((left, top, right, bottom)) # image.save("image{}.png".format(number)) return image def image_turn_num(self, image): """ 用获取的图片跟图片库的图片比较, :param image: 原图 :return: """ for i in range(0, 4): # 原图最多转三次 dir_path = "./static/images/" change_image = image.rotate(-90*i) # change_image.save("change{}.png".format(i)) for or_path in os.listdir(dir_path): or_image = Image.open(os.path.join(dir_path, or_path)) result = self.examine_pixel(or_image, change_image) if result: return i return 5 def examine_pixel(self, image1, image2): """ 判断来个图片是否相等 :param image1: 图片1 :param image2: 图片2 :return: """ thredhold = 100 for x in range(image1.size[0]): for y in range(image1.size[1]): pixel1 = image1.load()[x, y] pixel2 = image2.load()[x, y] if not (abs(pixel1[0] - pixel2[0]) < thredhold and abs(pixel1[1] - pixel2[1]) < thredhold and abs(pixel1[2] - pixel2[2]) < thredhold): return False return True def click_submit(self): """ 点击登录按钮 :return: None """ submit = self.wait.until(EC.element_to_be_clickable((By.ID, "btnLogin"))) submit.click() def __del__(self): self.browser.quit() def main(): """pass""" c = Crack() c.login() if __name__ == "__main__": main() [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDU3NjAxMA_size_16_color_FFFFFF_t_70]: /images/20220213/226bd493705345f7b31054e84fdce5aa.png
相关 Selenium实战【滑动验证码破解】【JAVA爬虫】 简介 本文主要讲解,利用之前所学到的java selenium如何实战操作,浏览器控制鼠标,模拟人工操作滑动验证码。这里需要用javacv 的代码知识,用于计算图像中滑块 左手的ㄟ右手/ 2024年03月30日 17:36/ 0 赞/ 125 阅读
相关 java爬虫破解滑块验证码 > 使用技术:java+Selenium > > 废话: > > 有爬虫,自然就有反爬虫,就像病毒和杀毒软件一样,有攻就有防,两者彼此推进发展。而目前最流行的反爬技术验证码 Dear 丶/ 2023年09月24日 14:26/ 0 赞/ 109 阅读
相关 破解滑动验证码 一、介绍 一些网站会在正常的账号密码认证之外加一些验证码,以此来明确地区分人/机行为,从一定程度上达到反爬的效果,对于简单的校验码Tesserocr就可以搞定,如下 ! 旧城等待,/ 2023年08月17日 16:21/ 0 赞/ 112 阅读
相关 [爬虫] 京东滑动验证码破解(selenium+python) 写在前面。 非原创,参考的是这篇文章,侵权转自己可见。 [https://blog.csdn.net/weixin\_45943597/article/details/10 ╰半夏微凉°/ 2022年10月07日 10:47/ 0 赞/ 649 阅读
相关 SpringMVC验证码生成,点击刷新及验证--基于kaptcha 直接看结果 实验结果 ![这里写图片描述][20160308153032876] 输入正确的验证码 ![这里写图片描述][20160308153044592] 输 川长思鸟来/ 2022年08月20日 06:10/ 0 赞/ 385 阅读
相关 点击生成动态验证码(工具类) 1.页面 <!--验证码--> <div class="col-sm-3"> <img id="vcode" src="/ch 喜欢ヅ旅行/ 2022年05月15日 15:51/ 0 赞/ 318 阅读
相关 servlet生成验证码和点击刷新验证码 javaweb项目,有两个文件,一个java文件,用来生成验证码并输出到servlet输出流中。一个html文件,用来写组件和点击事件,刷新验证码。 CodeServlet. - 日理万妓/ 2022年03月21日 06:46/ 0 赞/ 534 阅读
相关 爬虫验证码:破解【点击旋转验证码】 这里破解某某动漫的点击翻转验证码为例:![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cH 蔚落/ 2022年02月13日 11:13/ 0 赞/ 1175 阅读
相关 springboot文字图片点击验证码 说明:因为刷新的图标和点击图片文字的时候需要在图片上生成图标,为了美观,所以我引入Font Awesome图标库,如果你需要的话需引入该图标库方可使用 先上验证码效果图: 朱雀/ 2021年10月13日 02:53/ 0 赞/ 559 阅读
相关 python爬虫-破解验证码(封装超级鹰实现) 进入超级鹰首页,根据官方提示进行操作,下载python的文档后,把其封装进自己的第三方库中 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5n 本是古典 何须时尚/ 2021年09月07日 06:15/ 0 赞/ 743 阅读