美文网首页微信小程序开发
PMP成绩查询小程序(一)

PMP成绩查询小程序(一)

作者: 如果的if | 来源:发表于2020-01-31 22:43 被阅读0次

背景

我是一个程序员,在201906月参加了PMP考试,考试报名费3900,培训费2499。
虽然考试前做了充分的准备,听网课、刷视频、刷题。但是在考试时,还是很懵逼,毕竟刷题那么多,但是PMP还是没有原题这么一说。
由于担心考试成绩不够理想,考试后的那一个月,天天都在登录PMI网站查询成绩,特别是临近发布成绩的那几天,每天基本要查个4-5遍,生怕老美忘记了给我发成绩的邮件。
由于考试是分ABCDE卷的,大部分同学都收到邮件了,而我还是没收到邮件,所以我猜测我应该是E卷。所以在多久之后的一个晚上,大概11点左右,才收到成绩邮件,还好通过了考试,不然真对不起自己熬夜刷题的那几晚上(虽然程序员老熬夜)。
时过境迁啊,这段时间,微信培训班里的同学又开始了新一轮的成绩查询,几乎天天都在问班主任什么时候成绩能下来之类的话。看着电脑里面成绩邮件,可想当初对考试成绩所急迫的心理。索性,为了帮助他们方便查询成绩,我就做一个查询成绩的小程序,一来练习下小程序的开发,二来作为过来人也就当为你们这些学弟学妹做个贡献吧。

页面展示

小程序首页
结果1 结果2

所用技术

前台:微信小程序+支付宝小程序(uni-app)
后台:python(flask+requests+bs4)+ mysql + 腾讯云服务器

分析PMI网站代码

流程上只有2个重要节点

  1. 登录分析
  2. 成绩数据分析

PMI登录分析

  1. PMI登录页面
  • 用谷歌内核类的浏览器打开该网站


    登录页面
  • 点击F12,然后切到network页面


    network页面
  • 去登录页面随手输入账号1111111密码22222222
  • 查看network页面查看连接


    network2

此时找到第一个连接,可以看到提交的参数,其中包含了账号和密码
账号密码是明码(未加密),连加密流程都省下来了

  • 右键点击网页查看源代码
    此时可以找到上一个步骤中提交的参数及值信息,没有js自动生成的话,那就简单多了


    源代码

当然,提取这些参数,可以用正则的方式,也可以使用 BeautifulSoup(bs4)
正则和bs4相对来说,bs4取数的代码要整洁一些

报错信息

提示账号错误的信息也要提取出来,作为登录成功与否的提醒信息

登录伪代码

headers = {"Content-Type": "application/x-www-form-urlencoded",
               "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.68",
               "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
               "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
               "Accept-Encoding": "gzip, deflate, br"}

    analysis = "https://ccrs.pmi.org/reporting/examanalysis"
    dashboard = "https://ccrs.pmi.org/"
    login_url = "https://authentication.pmi.org/Default.aspx?r=ccrs.pmi.org&s=True"

    def login(self, uid, pwd, openid,platform = 'wechat'):
        global session
        self.session = requests.Session()
        r = self.session.get(self.login_url, headers=self.headers)
        soup = BeautifulSoup(r.text, 'html.parser')
        inputs = soup.find_all('input')
        params = {}
        for input in inputs:
            key = input.attrs.get('id', '')
            value = input.attrs.get('value')
            if 'tbUserName' in input.attrs.get('name'):
                key = key.replace('_', '$')
                value = uid
            elif 'tbPassword' in input.attrs.get('name'):
                key = key.replace('_', '$')
                value = pwd
            params[key] = value

        params['__EVENTTARGET'] = 'ctl00$ContentMain$bLogIn'
        r = self.session.post(url=self.login_url,
                              data=params, headers=self.headers)

        # 分析是否登录成功
        soup = BeautifulSoup(r.text, 'html.parser')
        error = soup.select_one('.error-msg')

        if error:
            return False, error.text.strip()
        else:
            return True, r.cookies.get_dict()

PMI成绩分析

  • 登录成功后的页面


    个人主页

登录后跳转到个人主页
右边CERTIFICATION STATUS这个地方是当次考试信息,也是我们需要获取的地方,点击view more on your dashboard

dashboard

这个网页就是我们需要获取的数据了,右键查看源代码

源代码

通过bs4,我们可以从中提取相应的数据

基础数据分析代码


def _dashboardExams(self, cookies):
        r = self.session.get(
            self.dashboard, headers=self.headers, cookies=cookies)
        soup = BeautifulSoup(r.text, 'html.parser')
        # 图表区域
        chart = soup.select('.chart-details')[-1]

        # 这个是基本信息
        span = chart.select('span')
        Credential = span[0].text
        Status = span[1].text
        Earned = span[2].text
        Renewal = span[3].text

        renewDay = soup.select_one('.status.renewal')
        renewDay = renewDay.select_one('em').text

        chart = soup.select('.toggle-container')[-1]
        em = chart.select('em')
        Required = em[0].text
        Applied = em[1].text
        Remaining = em[2].text

        return {'exams': [{'label': '证书号', 'content': Credential},
                          {'label': '状态', 'content': Status},
                          {'label': '取证日期', 'content': Earned},
                          {'label': '过期日期', 'content': Renewal},
                          {'label': '剩余过期天数', 'content': renewDay}], 
'pdus': [{'label': '总共需要', 'content': Required}, {'label': '已取得', 'content': Applied}, {'label': '还需', 'content': Remaining}],
                'crdate': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }

最后还有一个考试分析的圆饼图,打开 考试分析,见下图

原饼图

需要继续查看源代码,分析原饼图的数据,见下图

源代码

上图可以看到原饼图信息都是在html里面呈现,所以直接分析截取js代码就行了
用一个json格式化工具,找到关键节点即可

json

原饼图伪代码分析

def _analyExams(self, cookies):
        r = self.session.get(
            self.analysis, headers=self.headers, cookies=cookies)
        soup = BeautifulSoup(r.text, 'html.parser')
        data = {}
        # 获取成绩是否通过
        label = soup.select_one('.performance')
        result = label.text.strip().split(':')
        data['result'] =  result[-1]

        # 获取圆饼图
        script = soup.select_one('.pie-chart')
        script = script.text
        js_json = re.findall('kendoChart\((.+?)\);}\);', script)[0]
        j = json.loads(js_json)
        items = j['dataSource']['data']
        if items and len(items) > 0:
            data['items'] = []
            for item in items:
                label = item['Domain']
                color = item['Color']
                total = item['PercentageofTotal']

                data['items'].append(
                    {'color': color, 'label': label, 'total':  total, 'level': level})
        return data

小程序代码

小程序主要用uni-app跨平台框架来写的,其中他用的是vue的写法,我对vue也是刚学不久。套用了colorUI的外观以及ucharts的图表,还算把这个小程序给写下来了。

后台代码

总结

PMP考试相对于IPMP,CPMP恐怕要简单一些,每年的各个机构通过率都90%左右,所有各位有兴趣的话,可以考取一个,因为学习是一件终身的事情。
这次网站爬虫还是很简单的,毕竟所有数据都在页面可得,并不需要构造ajax请求就能获取。十分符合老美的风格。
另外,欢迎大家体验我做的小程序,目前已经上架 微信小程序和支付宝小程序。


微信小程序
支付宝小程序

小程序源代码下载gitee

相关文章

网友评论

    本文标题:PMP成绩查询小程序(一)

    本文链接:https://www.haomeiwen.com/subject/ltriictx.html