最近有个朋友的需求,用油猴写了一个插件,可以看五学教育(wuxuejiaoyu.cn)的网课

湖南环境生物职业技术学院 ,就是以前的湖南生物机电学校,成人高考需要看网课,问我有没有办法.我写了一个油猴插件,一天时间差不多把网课和考试都搞完了.....油猴还真的不错,

后台使用python  flask框架搭建了简易的服务器接口.

操作原理,第一次,随便选几个ABCD,先交卷,然后点击查看答案,查看答案的过程中会将所有题目和答案全部发送到后台保存,

第二次再考试就会自动匹配试卷.

以下是油猴代码

// ==UserScript==
// @name         wuxuejiaoyu查看答案
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        http://learning.wuxuejiaoyu.cn/openlearning/console/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=wuxuejiaoyu.cn
// @grant        none
// @require      http://code.jquery.com/jquery-3.x-git.min.js
// ==/UserScript==
/* globals jQuery, $, waitForKeyElements */

(function() {
    'use strict';
    $(document).ready(function() {
        console.info('进来了-查看答案');

        let intvals = setTimeout(()=>{
            console.info('进来了-查看答案2');
            let iframeDocument=$("iframe[name='w_main']")[0].contentWindow.document;
            if(iframeDocument){

                // console.info(iframeDocument);
                iframeDocument=iframeDocument.getElementById("cboxIframe").contentWindow.document;
                // console.info("2",iframeDocument);
                iframeDocument=iframeDocument.getElementById("w_lms_content").contentWindow.document;
                // console.info("3",iframeDocument);
                iframeDocument=iframeDocument.getElementById("w_lms_sco").contentWindow.document;
                //console.info("4",iframeDocument);
                //iframeDocument=$(iframeDocument).find("[name='w_right']")[0].contentWindow.document;
                //console.info("5",iframeDocument);

                var div = iframeDocument.getElementById("_block_content_exam_1") ;
                console.info('查看答案',div);
                if(div){

                    //console.info("取到了div")
                    //var trs = $(div).find("*[isitem]") ; //取到了题目表格
                    //console.info("查看答案trs",trs);
                    //trs = Array.from(trs);

                    var rtab = $(div).find("tr[correctstatus]")
                    //console.info("rtab的长度",rtab.length);

                    rtab = Array.from(rtab);
                    rtab.forEach((item,index)=>{

                        if($(item).attr("islabel")==1) return ; //如果是标题,例如选择题,就跳过
                        var text = "" ;
                        let isitem =$(item).find("table[isitem]");
                        if(isitem.length>0){
                            //第一种方式
                            text = isitem.find("tr").first().find("td:eq(0)").text();
                      //      console.info('第一种方式',text)

                        } else{

                            //第二方式
                            console.info("第二种方式读取",$(item).find("td:eq(1)"));
                            let div = $(item).find("td:eq(1)").find("div");
                            text = div.prop ('firstChild').nodeValue;
                        //    console.info('第2种方式',text)

                        }
                        // console.info("item",item);
                        // var text = $(item).find("tr:eq(0)").find("td:eq(1)").find("table[isitem]").html();
                        console.info(index,text);
                        //得到所有的选项
                        let contentTableTr = $(item).find("*[isitemoption]").find("tr") ; //取到了答案选项的表格
                        // console.info("选择题",contentTableTr.length);

                        let urls = 'http://127.0.0.1:5000/tiku/answerAndQuestion';

                        let data = {};


                        if(contentTableTr.length>0){

                            let content = contentTableTr.text();
                            let strs = $(item).find("div:contains('参考答案')").text();
                            strs = strs.split('参考答案')[1];
                            console.info('参考答案strs',strs)
                            let answer = strs.replace(/[^a-zA-Z]/g,'')
                            console.info('参考答案answer',answer)


                            data = {
                                'title':text, //问题标题
                                'content':text+' \n '+ content, //答案选项
                                'answer':answer,
                                'createTime':new Date().toLocaleString(),
                                'source':'wuxuejiaoyu',
                                'que_type':'10' //选择题

                            }
                        }else{
                            //展开简答题的参考答案
                            let ack = $(item).find("a:contains('展开参考答案')") ;
                            //console.info('a标签',ack);
                            ack[0].click();

                            //简答题
                            let title = $(item).find("*[issubitem]").find("td").text() ; //取到了答案选项的表格
                            //alert('简单题'+title);
                            let answer = $(item).text().split('参考答案')[1];
                            answer = answer.substr(5);
                            console.info("简答题答案",answer);
                            data = {
                                'title':title, //问题标题
                                'content':title, //答案选项
                                'answer':answer,
                                'createTime':new Date().toLocaleString(),
                                'source':'wuxuejiaoyu',
                                'que_type':'20' //简单题
                            }

                        }

                        $.ajax(
                            {
                                type: 'post',
                                url: urls,
                                cache: false,
                                data: JSON.stringify(data), //将data参数值转为json格式字符串
                                contentType: "application/json;charset=utf-8",
                                async:false,
                                success:function(res){
                                    console.info('得到的结果是',res)
                                }

                            }
                        );

                        //window.open(queryKeyword);
                        // }


                    })
                     alert('完成答案,请刷新页面之后再重新考试');

                    
                   
                    //location.reload();
                }
            }
        },10000)

        })
})();

  后台python

# -*- coding:utf-8 -*-
"""
www.sqjob.cn
author: liandyao
date: @date

"""
import re
from datetime import datetime

from lxml import etree
import requests

import SnowIds
import TiKu_MongoDb

import logging
logging.basicConfig(format='[%(asctime)s-%(name)s(%(levelname)s)%(filename)s:%(lineno)d]%(message)s', level=logging.DEBUG)

logger = logging.getLogger("ROOT")

# hots:mongodb服务器ip
# port:端口,默认为27017
# user:账号  【可选项】
# pwd:密码 【可选项】



class Tiku1():
    headers = {
        # 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
        'Referer': 'https://www.baidu.com/',
        'Content-Type': 'text/html;charset=utf-8',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
        ,'Host': 'www.baidu.com'
        ,'Cookie':'BIDUPSID=FE2D2E66C1689D888774DFF8F687BCBB; PSTM=1658233931; BD_UPN=19314753; BAIDUID=FE2D2E66C1689D888774DFF8F687BCBB:SL=0:NR=10:FG=1; H_BDCLCKID_SF_BFESS=tR-qVIK5tIK3H48k-4QEbbQH-UnLqMjw0mOZ04n-ah02DqFlMxOZXhFJyUcv5fopQ2cx-D5m3UTKsq76Wh35K5tTQP6rLtbQMnT4KKJxbp5sShOv5t5rDx_AhUJiBM7LBan7QpvIXKohJh7FM4tW3J0ZyxomtfQxtNRJ0DnjtpChbRO4-TFMjxK; BDUSS_BFESS=VxMXpmMk5uaW5DME9uOUh-REtCaXNiUldiWGpFeEZ0bU5QR3lhdzl6fnZKeFJqRUFBQUFBJCQAAAAAAAAAAAEAAABJoEgAy-rUws7eyfnKx9T4vq0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO-a7GLvmuxiR1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_PS_PSSID=36556_36461_36413_36954_36948_36165_36918_36919_36802_36789_36744_26350_36864_37022; sug=3; sugstore=0; ORIGIN=0; bdime=0; H_PS_645EC=fe28Yxr%2BR%2FK7QK7ySOElo6l4lFiVn6NfoIwkVHHptEd%2FiL6DdEWWFmzXEDw; BDSVRTM=0'
    }

    def __init__(self):
        self.url = "http://www.sqjob.cn"
        self.keyword=''
        # site:asklib.com

    # 利用百度查询https://www.baidu.com/s?wd=site: www.sqjob.cn '+text;
    def paBaidu(self, keyword):
        self.keyword=keyword
        self.url = 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=site:sqjob.cn ' + keyword
        logger.info(self.url)
        res = requests.get(self.url, headers=Tiku1.headers)
        res.encoding = 'utf-8'
        text = res.text

        html = etree.HTML(text)
        question = {
            "title": self.keyword,
            "content": '',
            "answer": '',
        }
        for i in range(1, 5):
            tatxt = html.xpath('//*[@id="'+str(i)+'"]/div/div[1]/h3/a/em/text()')
            # 如果匹配的关键字多余0个,并且第一个关键字匹配字符大于3个.那么就成功
            if (len(tatxt) > 0 and len(tatxt[0]) > 3):
                logger.info(''.join(tatxt))
                ahref = html.xpath('//*[@id="1"]/div/div[1]/h3/a/@href')[0]
                logger.info(ahref);
                return self.paUrl(ahref)

        return question
        # //*[@id="1"]/div/div[1]/h3/a
        # //*[@id="2"]/div/div[1]/h3/a

    # 爬取真正的url
    def paUrl(self,url):
        headers = {
            # 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
            'Referer': 'https://www.baidu.com/',
            'Content-Type': 'text/html;charset=utf-8',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.77',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
            , 'Host': 'www.baidu.com'
        }

        mongodb = TiKu_MongoDb.MongoClient('tiku_db')

        resa = requests.get(url, headers=headers, allow_redirects=False);
        # 得到网页原始地址
        real_url = resa.headers['Location']
        if real_url.startswith('http'):
            g_mu = real_url
            logger.info(g_mu)
            headers['Host']='www.sqjob.cn'
            resb = requests.get(g_mu, headers=headers)
            resb.encoding = 'gb2312'
            logger.info(resb.encoding)
            text2= resb.text
            #text2 = resb.content.decode('ISO-8859-1')

            html2 = etree.HTML(text2)
            content = html2.xpath('//*[@name="description"]/@content')[0]
            logger.info(content)
            description =content.replace(' ', '').replace('\n', '').replace('\r', '')

            ans = re.findall('(?<=答案是).*$', description)
            anss = re.findall(r'[A-D]',ans[0]);
            if len(anss)>1 :
                anss = "".join(anss)
            elif len(anss) == 1:
                anss = anss[0]
            else :
                anss = '未知'
            question={
                "que_id":SnowIds.IdWorker(1,1).get_id(),
                "title":self.keyword,
                "content":content,
                "answer":anss,
                "createTime":datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                "source":g_mu
            }
            mongodb.addQuestion(question=question)
            question.pop('_id')
            return question

        return None


if __name__ == "__main__":
    tk = Tiku1()
    tk.paBaidu('在Excel的自动筛选中,所选数据表的每个标题都对应着一个      。');

  代码未全部发布,有需要可以联系

posted @ 2022-08-07 21:26  liandyao  阅读(1007)  评论(2编辑  收藏  举报