工大助手(爬虫——查成绩部分)

工大助手(爬虫——查成绩部分)

基本内容

  • 工大助手(桌面版)
  • 实现登陆、查成绩、计算加权平均分等功能

团队人员

工大教务爬虫编写(查成绩)

查成绩的部分与登录类似,首先还是要分析网站的行为。登录到页面之后,进到如下页面:

点击成绩查询,进到了查询页面。通过浏览器的开发者工具,可以看到向http://gdjwgl.bjut.edu.cn/xscjcx.aspx 发送了相应的请求。其中参数有gnmkdm(含义是点击的哪个模块,比如查成绩),xh(学号),xm(姓名)。

但是在这里有一个难点,在于网页向http://gdjwgl.bjut.edu.cn/xscjcx.aspx 发送请求之后,并没有打开新的网页,而是在原网页上展示。仔细阅读了网页源代码之后,发现网页使用了iframe这个标签,但与此同时发现在请求标头中含有Referer这个属性,经过查询,发现这个属性用来记录从从哪个网站跳到此页面的,便可以根据这个返回到相应的页面。所以在构造请求数据时,在标头中要加上这个属性。
标头构造如下:

self.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586"
self.graduURL1 = "http://gdjwgl.bjut.edu.cn/xscjcx.aspx?xh=" + studentNo + "&xm=" + self.studentName + "&gnmkdm=N121605"
self.graduURL1 = urllib.quote(self.graduURL1,"?&/=:")
self.headers_gra2 = {'Referer': self.graduURL1,'user-Agent': self.user_agent}

构造请求时发现用户输入的只是学号信息,而发送请求中我们需要姓名信息。发现在页面的右上角有相应的姓名。我们利用BeautifulSoup——一个在pyhton中用来进行网页分析的包,对爬取下来的网页进行分析,将姓名提取出来,并作为请求的参数发送到相应的地址。

提取姓名如下:

# result为爬取的页面结果
soup = BeautifulSoup(result.read(),"html.parser")
tmp = soup.find(id="xhxm")
# 页面上的内容为xxx同学,所以需要截取一下字符串
self.studentName = str(tmp.string.decode('utf-8')[:-2])

进入到成绩页面后,我们可以发现历年成绩包含着我们全部成绩信息,所以我们只需要将这部分爬取下来就可以。同理,观察网页结构,构造请求信息如下:

postData_Gra = urllib.urlencode({
                '__EVENTTARGET':'',
                '__EVENTARGUMENT':'',
                'btn_zcj':'历年成绩',
                '__VIEWSTATE':self.viewstate,
                'hidLanguage': '',
                'ddLXN':'',
                'ddLXQ':'',
                'ddl_kcxz':''
            })

便可以获得成绩,但是获得成绩是由table标签组成的,所以之后我们利用xlwt——python中生成excel表的包,将成绩写入相应的excel表中。

def writeIntoExcel(self):
        pageCode = self.getPage()
        soup = BeautifulSoup(pageCode, 'html.parser')
        table = soup.find("table", class_="datelist")
        book = xlwt.Workbook(encoding="utf-8", style_compression=0)
        sheet = book.add_sheet("zf", cell_overwrite_ok=True)

        trs = table.find("tr")
        tds = trs.find_all("td")
        #print tds
        col = 0
        # 存入表格第一行,即每一列的说明
        for i in range(len(tds)):
            if i == 0 or i == 1 or i == 3:
                sheet.write(0, col, tds[i].find('a').string.decode("utf-8"))
                col += 1
            if i == 4 or i == 6 or i == 7 or i == 8 :
                sheet.write(0, col, tds[i].string.decode("utf-8"))
                col += 1
        # 存入详细成绩
        row = 0
        trs = table.find_all("tr")
        for i in range(len(trs)):
            if i > 0:
                tds = trs[i].find_all("td")
                row += 1
                col = 0
                for j in range(len(tds)):
                    if j == 0 or j == 1 or j == 3 or j == 4 or j == 6 or j == 7 or j == 8:
                        #print tds[j].string.decode("utf-8")
                        sheet.write(row, col, tds[j].string.decode("utf-8"))
                        col += 1
        book.save("score.xls")
        print "写入EXCEL完毕!"
原文地址:https://www.cnblogs.com/syncCN/p/5595373.html