最大的问题就是解决登录和验证码,登录之后get东西就简单了
作者:H我走路带风 原文地址:https://blog.csdn.net/a2272062968/article/details/115376592
示例源码:
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import requests import time import numpy import cv2 import os ''' 建议网速好一点执行此程序,否则可能会get不到资源导致程序终端或者get到的题目和答案为空 question_list_url 题目列表链接(只能是编程题的链接,其他题型同理判断一下即可我这里没写) file_name 要保存的文件名,我使用的markdown格式 access_interval 根据网速自定义设置,访问每到题的时间间隔s,访问太快总会被提示,不过我写了出现提示继续访问的逻辑; ''' def Programming_questions(question_list_url,file_name,access_interval): #创建 WebDriver 对象,指明使用chrome浏览器驱动 web = webdriver.Chrome(r'C:\Program Files\Google\Chrome\Application\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('xxxx@qq.com') mm.send_keys('xxxx') #找到登录按钮并点击 web.find_element_by_xpath('/html/body/div[1]/div[3]/div/div[2]/form/div[2]/button/div/div').click() for i in range(5): #等待一会,时间间隔可根据网速调整,验证码加载完成 time.sleep(3) print('当前url:'+web.current_url) #如果当前url没变说明验证未通过,循环5(可修改)次重新验证 if(web.current_url!='https://pintia.cn/auth/login'): break #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") #将背景图片转化为灰度图片,将三原色降维 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%,所以加了循环判断 #要get的题目集列表 web.get(question_list_url) #获取所以题目行 trp_problems = web.find_elements_by_xpath('/html/body/div/div[3]/div[3]/div/div[3]/table//tbody/tr') #存放所有题目的链接 problems_href=[] for tr in trp_problems: problems_href.append(tr.find_element_by_xpath('td[3]/a').get_attribute('href')) #count用来方便测试,如果中间程序断掉也可以通过修改count的值和条件判断从上次的地方继续执行 count = 0 filePro = open(file_name,'a') for problem in problems_href: if count>=0: #访问太快会被弹出提示页面,所以加个循环一直访问(循环次数自定义) for i in range(5): try: web.get(problem) time.sleep(access_interval) # 根据网速设置时间间隔,访问太快也会被提示 # 获取题目和答案 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) #写入格式是markdown文档:题目和代码 filePro.write('**' + tm_title + '**\n' + '```\n' + mycode + '\n```' + os.linesep) break #全部正常执行完说明没有弹出提示页面,退出即可 except: continue count += 1 print('--------------------------------完成数量'+str(count)+'---------------------------------------') filePro.close() if __name__ == '__main__': Programming_questions('https://pintia.cn/problem-sets/1371739727887736832/problems/type/7','test2.md',2.5)