本文主要是介绍一个小爬虫,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
长安大学招生情况分析
一直对爬虫和数据分析感兴趣,最近刚刚也找到一份工作,可以好好来做这件事了。
爬虫部分
2016/10/22
从上学期想自己写一个通过模拟登录来查成绩的程序说起吧。
初衷是因为每次查成绩需要去学校的信息门户查,而信息门户里面的查成绩系统兼容性差的老火的很,只支持古老的IE6,于是每次都需要切换到兼容模式,严重的时候还得到虚拟机用XP = =。所以萌生了模拟登录信息门户,自定义IE6的请求头来查成绩。模拟登录信息门户又是一个曲折的过程,暂且不表了。总之,成功模拟登录后我再去分析查成绩的过程,WTF,信息门户上查成绩居然是调用URP综合教务系统,更令人发指的是此系统的默认用户名和密码都是学号,so…
总之前两天我就想就在想既然高考分数等信息都在教务系统上,那么为什么不去做一下分析呢
接下来就是学号的部分了
学号一开始我的想法是通过规则生成学号,这样的效果就是用了四个for循环。呵呵。。。Fail
But, 昨天, 群里发布了体测的名单,惊喜的发现了有所有人的学号(当时我就这么认为的,事实证明我太naive了),所以今天到了学校,第一件事就是想办法提取excel文件里的数据。
不得不再次感叹一下
Life is short, I use Python
随便搜索一下python xls, 出现了一大堆结果,很容易就发现了xlrd和xlwr, 在这里我只需要安装一下xlrd就好了
pip install xlrd
读取xls部分
然后将数据写到文本里面方便提取
import xlrdfile = xlrd.open_workbook("F://2009.xls")
table = file.sheet_by_index(0)
count = 0
for value in table.col_values(2):value += "\n"count += 1with open("2009.txt", "a") as fh:fh.write(value)
print(count)
生成学号部分
然后在爬虫文件里面读取,这里用到了生成器(generator),毕竟数据有点大
def gen_id():"""This is for 2011-2015***Which is 12 bit"""#Before 2011 is 10 bitwith open("2009.txt", "r") as fh:for line in fh:"""after = ""after = line.replace("2013", "2011")after = after.replace("\n", "")"""line = line.replace("\n", "")yield line
注释掉的部分是将学号中代表入学年份的替换,结果后来证明这个想法也太naive了
模拟登录部分
def login(username):result = []session = requests.Session()base_page = session.get(BASE_URP_URL, headers=HEAD)#, proxies=proxy_)"""if base_page.status_code == 200:print("Connection OK! ")"""data = {'zjh':username,'mm':username,'dllx':'dldl'}index = session.post(LOGIN_URL,data=data, headers=HEAD)"""if index.status_code == 200:print("Login success. ")"""image = session.get(IMG_URL)img_content = image.contentuser_info_index = session.get(USER_INFO_URL,headers=HEAD)soup = user_info_index.text#content.decode('utf-8')result.append(soup)result.append(img_content)return result
写得渣见谅。本来想用代理的,在网上使用代理API获取了一些可用的代理,但会报
TypeError: can’t mix str and non-str argument
所以就先搁置了
分析部分用的是BeautifulSoup + lxml
数据库
用的是MySQL, 使用了第三方pymysql模块
keys = ""values = ""for key, value in user_info.items():key += ", "keys += keyvalue = "\'" + valuevalue += "\'"value += ", "values += valuetry:cur.execute('INSERT INTO students ({0}) VALUES ({1})'.format(keys.rstrip(", "), values.rstrip(", ")))except pymysql.err.IntegrityError as err:print("已存在")cur.connection.commit()
刚刚才发现百度文库里有完整的学生名单,不说了,我要去重新爬了
Update 10/24
今天早上又爬了一会,但奇怪的是03,10,16级的登陆不上。所以现在的数据只有十一年的,共50422条。
考虑到目前在校人数除研究生外大概2w余人,出入应该不大。
分析部分
各年份入学人数分析
年份 | 人数 |
---|---|
2005 | 3442 |
2006 | 3591 |
2007 | 4588 |
2008 | 5039 |
2009 | 5736 |
2010 | 6200(计划) |
2011 | 5511 |
2012 | 5988 |
2013 | 5844 |
2014 | 5238 |
2015 | 5333 |
注:
- 2010只抓到102条数据,舍弃。
- 斜体加粗代表数据来源于网络。
在这里用到了可视化数据工具Plotly,调用了其Python的API
import plotly.plotly as py
import plotly.graph_objs as gopy.sign_in('username', 'password')
trace0 = go.Bar(x=['2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015'],y=[3442, 3591, 4588, 5039, 5736, 6200, 5511, 5988, 5844, 5238, 5333],#text=['27% market share', '24% market share', '19% market share'],marker=dict(color='rgb(158,202,225)',line=dict(color='rgb(8,48,107)',width=1.5,)),opacity=0.6
)data = [trace0]
layout = go.Layout(title='2005-2015招生人数',
)fig = go.Figure(data=data, layout=layout)
try:py.iplot(fig, filename='test')
except KeyError:print("Success! ")
从上可以看出,从2005年开始招生人数是逐年上升的,
特别是在2007年进步颇高。
so why?
查看学校的档案馆,发现了2006年有下面几个事件值得关注
- 一月份学位委员会批准了多个博士点和硕士点
- 三月份新增一个专业
- 六月通过211,十五验收
- 七月行政班子换届;4个专业被授予名牌专业
可以看出,学校招生人数是逐年上升的,10年之后略有下降趋势,但都保持在5000人以上。
各省份录取人数
import pymysql
from collections import OrderedDict
provinces = ('北京', '天津', '上海', '重庆', '河北', '山西', '辽宁', '吉林', '黑龙江', '江苏', '浙江', '安徽', '福建', '江西', '山东', '河南', '湖北', '湖南', '广东', '海南', '四川', '贵州', '云南', '陕西', '甘肃', '青海', '台湾', '内蒙古', '广西', '西藏', '宁夏', '新疆', '香港', '澳门')
conn = pymysql.connect(host="127.0.0.1", port=3306, user="leo", password="mm123456", db="chd", charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)
cur = conn.cursor()
result = []
tmp = OrderedDict()
tmp1 = {}
for provice in provinces:for i in range(2005, 2016):cur.execute("select count(*) from chd.students where 入学日期 like '{0}____';".format(str(i)))total = cur.fetchone()['count(*)']cur.execute("select count(*) from chd.students where 入学日期 like '{0}____' and 考区 = '{1}';".format(str(i), provice))people = cur.fetchone()['count(*)']tmp[str(i) + ": "] = [people, (people / total)]tmp1[provice] = tmpresult.append(tmp1)tmp = OrderedDict()tmp1 = {}
cur.close()
conn.close()
print(result)
2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | |
---|---|---|---|---|---|---|---|---|---|---|---|
山东 | 197(5.72%) | 197(5.72%) | 249(5.43%) | 290(5.76%) | 300(5.23%) | 322(5.38%) | 272(4.65%) | 252(4.81%) | 271(4.97%) | ||
山西 | 133(3.86%) | 158(4.40%) | 188(4.10%) | 194(3.85%) | 220(3.84%) | 243(4.06%) | 272(4.65%) | 248(4.73%) | 266(4.88%) | ||
河北 | 170(4.94%) | 152(4.23%) | 231(5.03%) | 239(4.74%) | 289(5.03%) | 298(4.98%) | 325(5.56) | 295(5.63%) | 313(5.74%) | ||
河南 | 172(5.00%) | 151(4.20%) | 249(5.43%) | 285(5.66%) | 317(5.53%) | 370(6.18%) | 405(6.93%) | 372(7.10%) | 372(6.82%) | ||
湖北 | 135(3.92%) | 131(3.65%) | 139(3.03%) | 142(2.82%) | 162(2.82%) | 177(2.96%) | 158(2.70%) | 152(2.94%) | 152(2.82%) | ||
湖南 | 104(3.02%) | 111(3.09%) | 140(3.05%) | 152(3.02%) | 168(2.93%) | 174(2.91%) | 167(2.86%) | 154(2.94%) | 153(2.81%) | ||
广东 | 24(0.70%) | 25(0.70%) | 28(0.61%) | 26(0.52%) | 24(0.42%) | 55(0.92%) | 62(1.06%) | 66(1.26%) | 94(1.72%) | ||
广西 | 62(1.80%) | 56(1.56%) | 85(1.85%) | 83(1.65%) | 92(1.60%) | 117(1.95%) | 140(2.40%) | 136(2.60%) | 142(2.60%) | ||
黑龙江 | 66(1.92%) | 72(2.01%) | 75(1.63%) | 83(1.65%) | 87(1.52%) | 98(1.64%) | 75(1.28%) | 69(1.32%) | 68(1.25%) | ||
辽宁 | 71(2.06%) | 68(1.89%) | 72(1.57%) | 83(1.65%) | 92(1.60%) | 101(1.69%) | 76(1.30%) | 62(1.83%) | 62(1.14%) | ||
浙江 | 121(3.51%) | 116(3.23%) | 120(2.62%) | 139(2.76%) | 158(2.75%) | 157(2.62%) | 136(2.33%) | 114(2.18%) | 127(2.33%) | ||
安徽 | 105(3.05%) | 105(2.92%) | 172(3.75%) | 193(3.83%) | 213(3.71%) | 225(3.76%) | 245(4.19%) | 238(4.54%) | 253(4.64%) | ||
江苏 | 123(3.57%) | 116(3.23%) | 130(2.83%) | 134(2.66%) | 146(2.55%) | 144(2.40%) | 134(2.29%) | 128(2.44%) | 133(2.44%) | ||
福建 | 68(1.98%) | 61(1.70%) | 77(1.68%) | 85(1.69%) | 101(1.76%) | 103(1.72%) | 118(2.02%) | 103(1.97%) | 104(1.91) | ||
甘肃 | 77(2.24%) | 90(2.51%) | 115(2.51%) | 148(2.94%) | 203(3.52%) | 202(3.37%) | 239(4.09%) | 226(4.31%) | 228(4.18%) | ||
江西 | 66(1.92%) | 66(1.84%) | 85(1.85%) | 87(1.73%) | 107(1.87%) | 118(1.97%) | 112(1.92%) | 97(1.85) | 147(2.70%) | ||
云南 | 24(0.70%) | 24(0.67%) | 90(1.96%) | 83(1.65%) | 98(1.71%) | 101(1.69%) | 117(2.00%) | 122(2.33%) | 129(2.37%) | ||
贵州 | 28(0.81%) | 48(1.34%) | 81(1.77%) | 98(1.94%) | 124(2.16%) | 132(2.20%) | 145(2.48%) | 138(2.63%) | 158(2.90%) | ||
四川 | 93(2.70%) | 76(2.12%) | 97(2.11%) | 117(2.32%) | 116(2.02%) | 118(1.97%) | 125(2.14%) | 121(2.31%) | 153(2.81%) | ||
青海 | 55(1.60%) | 60(1.67%) | 69(1.50%) | 85(1.69%) | 96(1.67%) | 109(1.82%) | 95(1.63%) | 65(1.24%) | 52(1.00%) | ||
陕西 | 1106(32.13%) | 1168(32.53%) | 1429(31.15%) | 1575(31.26%) | 1724(30.06%) | 1716(28.66%) | 1557(26.64%) | 1358(25.93%) | 1321(24.23%) | ||
吉林 | 73(2.12%) | 76(2.12%) | 89(1.94%) | 87(1.73%) | 103(1.80%) | 101(1.69%) | 91(1.56%) | 80(1.53%) | 93(1.71%) | ||
宁夏 | 52(1.51%) | 64(1.78%) | 73(1.59%) | 85(1.69%) | 115(2.00%) | 124(2.07%) | 109(1.87%) | 72(1.37%) | 83(1.52%) | ||
海南 | 8(0.23%) | 14(0.39%) | 14(0.31%) | 25(0.50%) | 39(0.68%) | 50(0.84%) | 41(0.70%) | 34(0.65%) | 37(0.68%) | ||
西藏 | 9(0.26%) | 19(0.53%) | 20(0.44%) | 27(0.54%) | 31(0.54%) | 14(0.23%) | 13(0.25%) | 13(0.24%) | |||
内蒙古 | 78(2.27%) | 79(2.20%) | 104(2.27%) | 103(2.04%) | 120(2.09%) | 126(2.10%) | 120(2.05%) | 107(2.04%) | 102(1.87%) | ||
新疆 | 80(2.32%) | 113(3.15%) | 155(3.38%) | 174(3.45%) | 244(4.25%) | 248(4.14%) | 244(4.18%) | 190(3.63%) | 200(3.67%) | ||
北京 | 33(0.96%) | 33(0.92%) | 33(0.72%) | 37(0.73%) | 44(0.77%) | 40(0.67%) | 35(0.60%) | 33(0.63%) | 25(0.46%) | ||
天津 | 42(1.22%) | 60(1.67%) | 67(1.46%) | 70(1.39%) | 97(1.69%) | 95(1.59%) | 70(1.20%) | 73(1.39%) | 63(1.16%) | ||
上海 | 0(0.00%) | 3(0.08%) | 2(0.04%) | 1(0.02%) | 0(0.00%) | 0(0.00%) | 10(0.17%) | 17(0.29%) | 14(0.27%) | ||
重庆 | 67(1.95%) | 70(1.95%) | 91(1.98%) | 96(1.91%) | 103(1.80%) | 99(1.65%) | 97(1.66%) | 88(1.68%) | 114(2.09%) |
这篇关于一个小爬虫的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!