python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码


Posted in Python onJanuary 06, 2021

最近学了python爬虫,本着学以致用的态度去应用在生活中。突然发现算法的考试要来了,范围就是PTA刷过的题。让我一个个复制粘贴?不可能,必须爬它!

先开页面,人傻了,PTA的题目是异步加载的,爬了个寂寞(空数据)。AJAX我又不熟,突然想到了selenium。

selenium可以模拟人的操作让浏览器自动执行动作,具体的自己去了解,不多说了。干货来了:

登录界面有个图片的滑动验证码

python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码

破解它的最好方式就是用opencv,opencv巨强,自己了解。
思路开始:
1.将背景图片和可滑动的图片下载
2.用opencv匹配这两张图片的最匹配位置,不用在意怎么实现的,算法极其BT,不是我这种数学不及格的人能想的。最终会得到一个匹配度最高的XY值
3.由于Y值不用考虑,拖动滑块是X值的事情,调用selenium里抓放的函数,把X值丢进去,让浏览器自动滑动即可。
注意:由于算法问题,可能不能一次成功,重启程序就行了,或者改动代码。
4.进去之后就用selenium各种操作爬就完事了
以下是源码:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import requests
import time
import numpy
import cv2
import os

#作者:许文鸿
#未经允许不可转载,转载时注明出处

#创建 WebDriver 对象,指明使用chrome浏览器驱动
web = webdriver.Chrome(r'd:\chromedriver.exe')
web.implicitly_wait(5)
#调用WebDriver 对象的get方法 可以让浏览器打开指定网址
web.get('https://pintia.cn/auth/login')
zh = web.find_element_by_xpath('/html/body/div[1]/div[3]/div/div[2]/form/div[1]/div[1]/div/div/div[1]/input')
mm = web.find_element_by_xpath('/html/body/div[1]/div[3]/div/div[2]/form/div[1]/div[2]/div/div/div[1]/input')

#在PTA的账号密码:
zh.send_keys('******@qq.com')
mm.send_keys('******')
#找到登录按钮并点击
web.find_element_by_xpath('/html/body/div[1]/div[3]/div/div[2]/form/div[2]/button/div/div').click()
#等待两秒,验证码加载完成
time.sleep(2)
#bg背景图片
bg_img_src = web.find_element_by_xpath(
 '/html/body/div[3]/div[2]/div/div/div[2]/div/div[1]/div/div[1]/img[1]').get_attribute('src')
#front可拖动图片
front_img_src = web.find_element_by_xpath(
 '/html/body/div[3]/div[2]/div/div/div[2]/div/div[1]/div/div[1]/img[2]').get_attribute('src')
#保存图片
with open("bg.jpg", mode="wb") as f:
 f.write(requests.get(bg_img_src).content)
with open("front.jpg", mode="wb") as f:
 f.write(requests.get(front_img_src).content)
#将图片加载至内存
bg = cv2.imread("bg.jpg")
front = cv2.imread("front.jpg")
js = 'alert("本人可能将此程序用于python课设,请靓仔靓女不要直接提交本人代码。即将报错,需要删除第42~44行代码即可正常运行");'
web.execute_script(js)
time.sleep(15)
#将背景图片转化为灰度图片,将三原色降维
bg = cv2.cvtColor(bg, cv2.COLOR_BGR2GRAY)
#将可滑动图片转化为灰度图片,将三原色降维
front = cv2.cvtColor(front, cv2.COLOR_BGR2GRAY)
front = front[front.any(1)]
#用cv算法匹配精度最高的xy值
result = cv2.matchTemplate(bg, front, cv2.TM_CCOEFF_NORMED)
#numpy解析xy,注意xy与实际为相反,x=y,y=x
x, y = numpy.unravel_index(numpy.argmax(result), result.shape)
#找到可拖动区域
div = web.find_element_by_xpath('/html/body/div[3]/div[2]/div/div/div[2]/div/div[2]/div[2]')
#拖动滑块,以实际相反的y值代替x
ActionChains(web).drag_and_drop_by_offset(div, xoffset=y // 0.946, yoffset=0).perform()

#至此成功破解验证码,由于算法问题,准确率不能达到100%,可能需要多运行1~2次

for page in range(0, 1000):
 time.sleep(1)
 #此处的网址为PTA固定网页,仅需要更换page
 web.get('https://pintia.cn/problem-sets?tab=1&filter=all&page={page_}'.format(page_=page))
 #获取当前页面题目集网址,A_s为a标签的列表,urls用户存放网址
 A_s = web.find_elements_by_class_name('name_QIjv7')
 urls = []
 for a in A_s:
  urls.append(a.get_attribute('href'))
 #当页面不存在可爬取的网址,则退出程序
 if urls.__len__() == 0:
  print('爬取完成')
  os._exit()
 #对刚才获取的网址列表进行遍历
 for url in urls:
  web.get(url)
  #找到对应的题目对象
  tm = web.find_elements_by_css_selector("[class='problemStatusRect_3kpmC PROBLEM_ACCEPTED_1Dzzi']")
  tm_total = 0
  for i in range(0, 1000):
   # 遍历该页面的题型
   try:
    tm_type = web.find_element_by_xpath(
     '/html/body/div/div[3]/div[2]/div/div[2]/div[{i_}]/div/div[2]'.format(i_=i * 2 + 2)).text
    # 如果题型为编程/函数,记录对应的数量,方便后续爬取
    if tm_type == '编程题' or tm_type == '函数题':
     tm_total += int(web.find_element_by_xpath(
      '/html/body/div/div[3]/div[2]/div/div[2]/div[{i_}]/a/div/div'.format(i_=i * 2 + 2)).text[0])
   except:
    break
  # 根据函数/编程题数量取相应的题目对象,舍弃其他题目
  if tm_total != 0:
   tm = tm[-tm_total:]
  else:
   tm = []
  # 遍历剩余题目
  for tm_index in tm:
   try:
    tm_index.click()
    time.sleep(0.5)
    #获取题目中的代码
    tm_title = web.find_element_by_css_selector(
     "[class='text-center black-3 text-4 font-weight-bold my-3']").text
    mycode = web.find_element_by_css_selector('textarea').get_attribute('value')
    print('题目:' + tm_title)
    print(mycode)
    #接下来可以存入
   except:
    continue

到此这篇关于python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码的文章就介绍到这了,更多相关python图片滑动验证码内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python3下使用cv2.imwrite存储带有中文路径图片的方法
May 10 Python
Pycharm取消py脚本中SQL识别的方法
Nov 29 Python
python 获取毫秒数,计算调用时长的方法
Feb 20 Python
Python和Java的语法对比分析语法简洁上python的确完美胜出
May 10 Python
Python3安装psycopy2以及遇到问题解决方法
Jul 03 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
Jul 15 Python
导入tensorflow时报错:cannot import name 'abs'的解决
Oct 10 Python
python golang中grpc 使用示例代码详解
Jun 03 Python
使用Keras实现简单线性回归模型操作
Jun 12 Python
Python通过递归函数输出嵌套列表元素
Oct 15 Python
Python使用scapy模块发包收包
May 07 Python
python基础之错误和异常处理
Oct 24 Python
python 获取谷歌浏览器保存的密码
Jan 06 #Python
python实现PolynomialFeatures多项式的方法
Jan 06 #Python
pytorch中index_select()的用法详解
Jan 06 #Python
Python之京东商品秒杀的实现示例
Jan 06 #Python
Python实现小黑屋游戏的完整实例
Jan 06 #Python
Jupyter Notebook 安装配置与使用详解
Jan 06 #Python
在Ubuntu中安装并配置Pycharm教程的实现方法
Jan 06 #Python
You might like
php绘图之在图片上写中文和英文的方法
2015/01/24 PHP
Laravel 5框架学习之日期,Mutator 和 Scope
2015/04/08 PHP
PHP简单实现循环链表功能示例
2017/11/10 PHP
解决PHP curl或file_get_contents下载图片损坏或无法打开的问题
2019/10/11 PHP
PHP 实现 JSON 数据的编码和解码操作详解
2020/04/22 PHP
js兼容标准的表格变色效果
2008/06/28 Javascript
jValidate 基于jQuery的表单验证插件
2009/12/12 Javascript
javascript encodeURI和encodeURIComponent的比较
2010/04/03 Javascript
jquery实现奇偶行赋值不同css值
2012/02/17 Javascript
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
2012/07/31 Javascript
基于jQuery仿淘宝产品图片放大镜特效
2020/10/19 Javascript
AngularJS在IE下取数据总是缓存问题的解决方法
2016/08/05 Javascript
jQuery插件FusionWidgets实现的AngularGauge图效果示例【附demo源码】
2017/03/23 jQuery
Angularjs的$http异步删除数据详解及实例
2017/07/27 Javascript
JavaScript代码判断输入的字符串是否含有特殊字符和表情代码实例
2017/08/17 Javascript
微信小程序实现多选功能
2018/11/04 Javascript
说说如何利用 Node.js 代理解决跨域问题
2019/04/22 Javascript
Node.js 实现远程桌面监控的方法步骤
2019/07/02 Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
2019/08/20 Javascript
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
[00:31]DOTA2荣耀之路7:Miracle-空血无敌斩
2018/05/31 DOTA
win7 x64系统中安装Scrapy的方法
2018/11/18 Python
举例讲解Python常用模块
2019/03/08 Python
python实现BP神经网络回归预测模型
2019/08/09 Python
python scipy卷积运算的实现方法
2019/09/16 Python
pytorch逐元素比较tensor大小实例
2020/01/03 Python
jupyter notebook 多行输出实例
2020/04/09 Python
基于HTML5超酷摄像头(HTML5 webcam)拍照功能实现代码
2012/12/13 HTML / CSS
经销商订货会主持词
2014/03/27 职场文书
农村党支部书记四风问题个人对照检查材料
2014/09/21 职场文书
商铺门面租房协议书
2014/10/21 职场文书
小学工作总结2015
2015/05/04 职场文书
2016年寒假见闻
2015/10/10 职场文书
电工生产实习心得体会
2016/01/22 职场文书
mysql5.6主从搭建以及不同步问题详解
2021/12/04 MySQL
利用Python实现模拟登录知乎
2022/05/25 Python