青岛大学教务爬虫

# -*- coding: utf-8 -*-

from PIL import Image
import io
import re
import getpass
import requests
import pytesseract
from lxml import etree
from prettytable import PrettyTable


class qdujw:
    def __init__(self):
        self.userid = 0
        self.s = requests.Session()
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36'
        }

    # 教务登录
    def login(self):
        global sid, passwd, jw
        loginurl = 'http://jw.qdu.edu.cn/academic/j_acegi_security_check'
        codeurl = 'http://jw.qdu.edu.cn/academic/getCaptcha.do'
        userurl = 'http://jw.qdu.edu.cn/academic/showPersonalInfo.do'

        # 验证码
        code = self.s.get(codeurl, headers=self.headers, stream=True)
        img = Image.open(io.BytesIO(code.content))

        # 降噪
        threshold = 140
        table = []
        for i in range(256):
            if i < threshold:
                table.append(0)
            else:
                table.append(1)

        # 将彩色图像转换为灰度图像
        imgry = img.convert('L')

        # 讲图像中噪声去除
        out = imgry.point(table, '1')

        codetext = pytesseract.image_to_string(out, config='digits')

        # 去除空格,将.替换为0
        codetext = codetext.replace(' ', '')
        codetext = codetext.replace('.', '0')

        # 登录
        postdata = {
            'j_username': sid,
            'j_password': passwd,
            'j_captcha': codetext
        }
        r = self.s.post(loginurl, postdata)

        # 密码错误
        if re.search(u'\u5bc6\u7801\u4e0d\u5339\u914d', r.text):
            print sid + ' 密码不匹配!'
            print
            choice = raw_input('请选择(1.重新输入 2.退出):')
            if choice == '1':
                sid = raw_input('学号:')
                passwd = getpass.getpass('密码:')
            else:
                exit()
            jw.login()

        # 用户名不存在
        elif re.search(u'\u4e0d\u5b58\u5728', r.text):
            print sid + ' 用户名不存在!'
            print
            choice = raw_input('请选择(1.重新输入 2.退出):')
            if choice == '1':
                sid = raw_input('学号:')
                passwd = getpass.getpass('密码:')
            else:
                exit()
            jw.login()

        # 验证码错误
        elif re.search(u'\u9a8c\u8bc1\u7801\u4e0d\u6b63\u786e', r.text):
            print '正在登录,请耐心等待......'
            jw.login()

        # 成功
        else:
            userpage = self.s.get(userurl).content
            name = etree.HTML(userpage.decode(
                'utf-8', 'ignore')).xpath('/html/body/center/table[1]/tr[1]/td[2]/text()')
            for n in name:
                name = n.encode('utf-8')
            userid = re.findall(b'.*?userid=(.*?)"', userpage, re.S)
            for i in userid:
                self.userid = self.userid * 10 + int(i)
            print name + '登录成功!'

    # 查询成绩
    def scores(self):
        print '======= 成绩查询 ========'
        print
        year = raw_input('请输入查询学年: ')
        term = raw_input('春季学期输入[1],秋季学期输入[2]: ')
        scoresurl = 'http://jw.qdu.edu.cn/academic/manager/score/studentOwnScore.do'

        # 字符串计算  eval()
        postdata = {
            'year': eval(year + '-' + '1980'),
            'term': term,
            'para': '0'
        }
        scorespage = self.s.post(scoresurl, postdata).content
        aa = '<td>' + year + '[\s\S]*?<td>.*?</td>[\s\S]*?<td>.*?</td>[\s\S]*?<td>([\s\S]*?)</td>[\s\S]*?<td>.*?</td>[\s\S]*?<td>([\s\S]*?)</td>'

        # str转types  .encode(encoding="utf-8")
        scores = re.findall(aa.encode(encoding="utf-8"), scorespage, re.S)

        print
        print '======= 考试成绩 ========'
        for s in scores:
            print
            print s[0].strip()+' : '+s[1].strip()

    # 查询课表
    def kebiao(self):
        print '======= 课表查询 ========'
        print
        year = raw_input('请输入查询学年: ')
        term = raw_input('春季学期输入[1],秋季学期输入[2]: ')
        print

        # 使用 PrettyTable 打印表格
        x = PrettyTable(["周一", "周二", "周三", "周四", "周五", "周六", "周日"])
        x.padding_width = 1
        get = {
            'id': self.userid,
            'yearid': eval(year + '-' + '1980'),
            'termid': term,
            'timetableType': 'STUDENT',
            'sectionType': 'COMBINE'
        }

        kb = self.s.get(
            'http://jw.qdu.edu.cn/academic/manager/coursearrange/showTimetable.do', params=get)
        html = etree.HTML(kb.content)

        kb = html.xpath('//*[@id="timetable"]//*[@class="center"]')
        i = 0
        list = []
        list1 = ['', '', '', '', '', '', '']
        for k in kb:
            # print k.xpath('string()').encode('utf-8')

            # 通过 list 将课程信息添加到 PrettyTable 中
            if i < 7:
                list.append(
                    k.text.split(';')[0].replace('<<', '').replace('>>', ''))
                i += 1
                if i == 7:
                    # 上下显示一行空白,方便阅读
                    x.add_row(list1)
                    x.add_row(list)
                    x.add_row(list1)
                    list = []
                    i = 0
        print x

    # 教务通知
    def news(self):
        newsurl = requests.get(
            'http://jw.qdu.edu.cn/homepage/infoArticleList.do;jsessionid=E06A6E2B5FA3F797FAB8FA5F6331AC92?columnId=358')
        html = etree.HTML(newsurl.content.decode('utf-8', 'ignore'))
        news = html.xpath('//*[@id="thirdcontent"]/div[2]/ul/li/div/a')
        for new in news:
            print new.xpath('string(.)').encode('utf-8').replace(' ', '').replace('\n', '')
            print 'http://jw.qdu.edu.cn/homepage/' + new.attrib['href']
            print

    # 个人信息
    def user(self):
        print '======= 个人信息 ========'
        print
        user = self.s.get('http://jw.qdu.edu.cn/academic/showPersonalInfo.do')
        html = etree.HTML(user.content.decode('utf-8', 'ignore'))
        for n in html.xpath('/html/body/center/table[1]/tr[1]/td[2]/text()'):
            print '姓名: ' + n.encode('utf-8')
        for n in html.xpath('/html/body/center/table[1]/tr[2]/td[1]/text()'):
            print '院系: ' + n.encode('utf-8')
        for n in html.xpath('/html/body/center/table[1]/tr[2]/td[2]/text()'):
            print '专业: ' + n.encode('utf-8')
        for n in html.xpath('/html/body/center/table[1]/tr[4]/td[1]/text()'):
            print '年级: ' + n.encode('utf-8')
        for n in html.xpath('/html/body/center/table[1]/tr[4]/td[2]/text()'):
            print '班级: ' + n.encode('utf-8')

jw = qdujw()
print '======== 教务通知 ========'
jw.news()
print

print '======== 登录教务系统 ========'

# 学号和密码
print '请输入学号和密码'
sid = raw_input('学号:')
passwd = raw_input('密码:')
jw.login()

while 1:
    print
    print '======== 青岛大学教务系统 ========'
    print
    print '[1]查询成绩'
    print '[2]查询课表'
    print '[3]个人信息'
    print '[4]退出'
    print
    choice = raw_input('请选择: ')
    print
    if choice == '1':
        jw.scores()
    elif choice == '2':
        jw.kebiao()
    elif choice == '3':
        jw.user()
    elif choice == '4':
        exit()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值