一个小爬虫

2024-09-02 22:08
文章标签 小爬虫

本文主要是介绍一个小爬虫,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

长安大学招生情况分析

一直对爬虫和数据分析感兴趣,最近刚刚也找到一份工作,可以好好来做这件事了。


爬虫部分

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余人,出入应该不大。


分析部分

各年份入学人数分析

年份人数
20053442
20063591
20074588
20085039
20095736
20106200(计划)
20115511
20125988
20135844
20145238
20155333

注:

  • 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)
20052006200720082009201020112012201320142015
山东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%)

这篇关于一个小爬虫的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131197

相关文章

Python 小爬虫:爬取 bing 每日壁纸设为桌面壁纸

请求 URLJSON 版示例代码代码片段注意点headers 中的 User-Agent响应头中的 Content-Type终端通过代理 API从 bing.com 找Bing 每日壁纸设置为桌面壁纸代码设定计划任务自动执行 python 脚本 请求 URL 通过模仿必应(Bing)自己的 AJAX 调用方式获得请求 URL。 JSON 格式:

歌谱简谱网的小爬虫,用着贼爽!

歌谱简谱网的乐谱,一个一个下载感兴趣的歌谱图片费时费力,没有效率,很不痛快。 干脆弄条爬虫,喜欢哪首乐谱,就把乐谱所在的网址粘贴进去,就行啦,爬虫帮你自动建立文件夹下载到本地,用着贼爽! 网站地址:http://www.yidianqiuxun.com 具体代码如下: import reimport osimport requests'''使用方法:代码复制到py文件中,保存,关

5分钟从零开始构建一个Node.js小爬虫程序并生成网站

通过RSS2JSON和Node.js设计一个简单的小爬虫 阅读这篇blog大约需要5分钟 之前我们学习了解了很多Node.js、云部署的基础知识,今天通过一个小爬虫练习实践一下,你会发现从零开始构建一个小爬虫超级简单和方便。主要会涉及到这些知识点: 通过RSS2JSON将rss转化为json格式MUI CSS设计极简风格Node.js异步编程axios模块cheerio模块通过heroku上

node.js学习笔记--HTTP之Promise重写小爬虫

注:此博客是在学习进击Node.js基础(一)这门课程时的学习笔记,感谢Scott老师的课程。 一、使用Promise处理异步、嵌套 1. 用传统的回调来按顺序执行小球动画 <!doctype><html><head><title>Promise animation</title><style>.ball{width: 40px;height:40px;border-radius: 20

node.js学习笔记--HTTP之小爬虫

注:此博客是在学习进击Node.js基础(一)这门课程时的学习笔记,感谢Scott老师的课程。 一、开启HTTP请求 var http = require('http') //调用http模块http.createServer(function(req, res){ //res是response响应,req是request请求res.writeHead(200,{'Content-Type':

美女图片小爬虫,嘿嘿

/*** Created by Administrator on 2016/9/22 0022.*///依赖的模块var http=require('http');var fs=require('fs');var cheerio=require('cheerio');var request=require('request');var iconv = require('iconv-l

58同城python委培生需要收费吗_初次小爬虫:58同城招聘信息爬取

1,通过url获取html url="http://bj.58.com/job/pn"+pagenumber+'/?key=python&final=1&jump=1&PGTID=0d000000-0000-046d-babb-93654e2239c8&ClickID=2' r=requests.get(url,headers=headers,timeout=30) r.raise_for_st

PHP小爬虫

首先新建一个函数文件func.php <?php//func.php//使用给定的URL下载图片并保存为特定文件function get_image($url,$filename,$timeout=5){$file = fopen($filename, 'w+');$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);//设定需要回去的URL

用java做一个简易的小爬虫(可以爬美女图片哦)

前言 爬虫一直python的强项,其它语言也能做,只是没有python那么方便快捷,今天正好学到java中了一些和网络相关的知识,就做了一个小爬虫。 主要功能是:爬取百度图片中的图片,一键下载。 效果图 话不多说,先上效果图 功能就是这样,根据输入的关键字不同,自动下载不同的图片,当然,这些图片都是从百度图片中爬取出来的。 思路 随便输入一个关键字,百度图片就会展示出很多图片