Python xlrd xlwt读写Excel

需求:给你一个学生名单(Excel表格),统计在一个比赛(开放)中,名单上所有学生的AC情况,要求语言是java

名单上有三列:学号,姓名,分组 最后统计的时候我在新表格中加了三列:OJ昵称,AC数量,非JAVA语言AC的数量

其实这个任务一开始对我来说真有点困难,主要是用Python操作Excel,这个我之前没接触过,而且和网页爬虫结合在一起,即把爬虫爬下来的数据整理后写入新的Excel表格,我感觉,整个过程最头疼最重要的应该是数据结构的组织了,幸好Python内置的数据结构(列表,字典等)用起来都很灵活,我把整个过程分成了四个部分完成,注释里写得很详细啦~ 用了两天多的时间(并不是一直在弄,我还要上课,写作业.....)最后再说一下时间问题,,,实际上昨晚我就写出来了,但是运行起来好慢,,,等了几秒,光标都不闪了,我以为程序死循环了QAQ,找了好久也没发现问题,事实是它真的很慢,今天我特意等了几十秒,终于等出了结果,可能是ACM中毒比较深吧2333

(我又修改了一些地方)

#!/usr/bin/env python
#-*-coding:utf-8-*-

import sys, os
import xlrd, xlwt
import urllib, urllib2, cookielib
from bs4 import BeautifulSoup as BS

#1.登录OJ,主要用到的模块:urllib, urllib2, cookielib
home = 'http://acm.sdut.edu.cn/onlinejudge2/index.php/Home'  
login = 'http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Login/login' 

cookie_support = urllib2.HTTPCookieProcessor(cookielib.CookieJar())  
opener = urllib2.build_opener(cookie_support)  
urllib2.install_opener(opener) 
temp = urllib2.urlopen(home) 

username = raw_input('请输入用户名:\n')
password = raw_input('请输入密码:\n')

value = {'user_name': username, 'password': password}
headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0'}

post = urllib.urlencode(value)
response = urllib2.urlopen(urllib2.Request(login, post, headers))
soup = BS(response.read())
if soup.find(text = 'Logout') != None:
    print '登录成功!'
else:
    print '登录失败,请重新登录!'
    sys.exit(0)     #退出程序

#2.获取学生名单的数据,主要用到的模块:xlrd
workbook = xlrd.open_workbook(os.getcwd() + '/Lists_15_Software.xlsx') #获得文件路径,打开Excel表格
sheet1 = workbook.sheet_by_name('Sheet1')
data = []
for row in range(1, sheet1.nrows):
	info = []
	info.append(int(sheet1.cell(row, 0).value))#学号
	info.append(sheet1.cell(row, 2).value)	   #分组
	info.append('无提交')  #OJ昵称,默认为无提交
	info.append(0)	      #AC,默认为0
	info.append(0)        #非JAVA提交,默认为0
	data.append(((sheet1.cell(row, 1).value, info)))
data = dict(data)         #得到以学生名字为键的字典

#3.解析排名榜,主要用到的模块:BeautifulSoup
cid = raw_input('请输入比赛的id:\n')
url = 'http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestranklist/cid/' + cid
soup = BS(urllib2.urlopen(url).read())
def Java(href):           #统计每个学生JAVA语言AC的数量
	t = set()
	while True:
		sub = BS(urllib2.urlopen(href).read())
		for tr in sub.find_all('tr'):
			td = tr.find_all('td')
			try:
				if td[3].text == 'Accepted' and td[6].text == 'java':
					t.add(td[2].text)
			except:
				pass
		try:
			href = 'http://acm.sdut.edu.cn' + sub.find(class_ = 'next')['href']
		except:
			return len(t)

for tr in soup.find_all('tr'):
	td = tr.find_all('td')
	if td:
		nickname = td[1].text
		href = td[2].a.get('href')
		ac = int(td[2].text)
		try:
			if nickname[-3].isdigit():
				name = nickname[-2:]
			else:
				name = nickname[-3:]
			data[name][2] = nickname
			data[name][3] = ac
			data[name][4] = ac - Java('http://acm.sdut.edu.cn' + href)
		except:
			pass
temp = []
for key in data:
	temp = data[key]
	temp.append(key)       #把字典中的键(名字)也加入值(列表)中
data = list(data.values()) #舍弃键,只取包含所有数据的值(列表)
def my_cmp(a, b):          #sort的cmp函数
	if a[1] > b[1]:
		return 1
	if a[1] < b[1] or a[3] > b[3]:
		return -1
	if a[3] < b[3]:
		return 1
	return 0
data.sort(cmp = my_cmp)    #排序,分组正序,AC逆序

#4.写入文件,主要用到的模块:xlwt
workbook = xlwt.Workbook(encoding = 'utf-8') #创建表格
sheet1 = workbook.add_sheet('Sheet1')
sheet1.col(0).width = 3500 #设置单元格宽度
sheet1.col(3).width = 4500
style = xlwt.easyxf('alignment: horz center, vert center')      #设置样式,居中
row0 = [u'学号', u'姓名', u'分组', u'OJ昵称', u'AC', u'非JAVA提交']#表格第一行
for i in range(6):
	sheet1.write(0, i, row0[i], style)
i = 1 
for value in data:         #将数据写入表格
	sheet1.write(i, 0, value[0], style)
	sheet1.write(i, 1, value[5], style)
	sheet1.write(i, 2, value[1], style)
	sheet1.write(i, 3, value[2], style)
	sheet1.write(i, 4, value[3], style)
	sheet1.write(i, 5, value[4], style)
	i += 1                 #行数加一
workbook.save('data.xls')  #保存表格

一个测试的结果(cid-2038):


  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值