- init.js :用来初始化项目,主要是用来建立文件夹,比如
data,log。需要在项目运行前先运行该文件,以避免因为文件夹不存在引起fs模块的报错。 - crawl: 数据爬取,其子文件夹如下:
- data: 用来存储提前批、大学分数线、大学专业分数线、ucode等数据,其子文件夹的结果如下:
- collegeScoreLines: 院校分数线数据。
- preFraction:提前批数据。
- professionScoreLines: 院校专业分数线信息。
- ucode:大学在各省份对应的
ucode。
每个文件夹的子文件夹都是一样的,包括
data,html,json。用途如下:- data:用来存储接口获取的数据以及将数据解析后进行存储,有两个子文件夹:
- encrypt:接口响应数据,是加密数据。
- decrypt:将
encrypt文件夹进行解析,其结构与encrypt一模一样。
- html:如果需要爬取网页的源代码,那么就把页面的
.html文件保存在该文件夹下。 - json:将
html文件夹中的代码进行解析,将需要的数据保存为自己想要的格式。
- html: 存的是各个省份的id和名称的页面代码,从浏览器那里复制而来。
- json:存放省份id和省份名称的json文件,使用频繁。
- colleges.js: 获取院校分数线的
js文件,需要单独运行,运行命令node colleges.js。 - preFraction.js: 获取提前批数据的
js文件,需要单独运行,运行命令node preFraction.js。 - professions.js: 获取院校各专业分数线的
js文件,需要单独运行,运行命令node professions.js。 - ucode.js: 获取各个学校在各个省份对应的
ucode的js文件,需要单独云南行,运行命令node ucode.js。 - province.js:生成省份信息的json文件,放在
json文件夹。需要单独运行,运行命令node province.js
- data: 用来存储提前批、大学分数线、大学专业分数线、ucode等数据,其子文件夹的结果如下:
- log:存放运行日志的文件夹,通过
init.js生成该文件夹。 - services:从浏览器保存下来的
js文件。 - utils: 用来解析密文,日志配置,程序等待等。
- 接口
- request
- url:https://ia-pv4y.youzy.cn/preFraction/index
- method: get
- header
- Cookie: 需要有省份信息,是必须的
let p = { "provinceId": key, "provinceName": provinces[key], "isGaokaoVersion": false } let cookie = encodeURI(JSON.stringify(p))
- params
- p: 加密后的省份信息
let encryptP = common.youzyEpt(p)- toUrl: 固定参数,'/preFraction/index'
- response
- data: 请求到的数据,res.data 就可以拿到网页代码。
- request
省份信息例子: { "provinceId": 842, "provinceName": '上海', "isGaokaoVersion": false },isGaoKaoVersion 目前不清楚它的作用是什么,都是写固定为 false。
- 分析爬取下来的网页代码,部分省份是没有提前批的院校信息的,所以最后没有生成该省份对应的
json文件。 - json文件结构,其中的 typeId 是用来获取批次信息的关键参数。
{
"province": "安徽",
"provinceId": "844",
"name": "体育批本科",
"colleges": [
{
"pcid": "828",
"name": "体育类第一批(本科)",
"pcxs": [
{
"typeId": "829",
"name": "平行志愿投档前单独投档录取"
},
{
"typeId": "830",
"name": "平行志愿投档院校"
}
]
}
]
}一个省份中有多种批次类别,如 体育批本科,艺术批本科,艺术批专科等。每种类别中又有多个学校,每个学校中又有多个批次,如 艺术类第四批,艺术类第五批。每个批次中又有多个项目,如 平行志愿投档前单独投档录取,平行志愿投档院校。可以看网站的批次信息页面,就可以更好地理解。
- request
- url: https://ia-pv4y.youzy.cn/Data/TZY/PreFraction/QueryWithApp
- method: post
- header
- Cookie
// 请求头部添加省份信息的 cookie let p = { "provinceId": provinceId, "provinceName": provinceName, "isGaokaoVersion": false } let cookie = encodeURI(JSON.stringify(p)) OPTIONS.headers = { 'Cookie': `YouzyPV_currentProvince=${cookie}` }
- params
- data: 加密后的请求参数,使用
common.youzyEpt(queryObj),queryObj 的内容如下
{ typeId: typeId, pageIndex: 1, pageSize: PAGE_SIZE, // 网站是一页获取 5 条,所以这里也是遵循网页的方式 provinceId: provinceId, year: year, course: -1 // 这个应该是文科生还是理科生的标志位,这个接口没用到这个参数,所以用 -1 表示不碍事 }
- data: 加密后的请求参数,使用
- response
"result": { "totalCount": 17, // 该批次总共有几个学校 "items": [ { "types": [], // 不清楚 "colleges": [ // 学校列表 { "typeId": 100159, // 查询参数中的 typeId "admissCode": "gc7nim29|c7olgo13|crp7qr19|scj7ng13|", // 应该时学校编码 "collegeId": 907, "collegeName": "【上】|cr6miobb|【电】|cnjs6r55|c6osr6qf|c6lrr7j4|", "course": null, "bzType": null, "admissType": null, "planNum": "crnqk2ej7a|", // 计划招生数 "cost": "-", "learnYear": "-", "remarks": "", // 备注 "majors": [ { "majorCode": "", // 专业代码 "professionName": "【电】|ptnc6kb5|qpgsc684|otch6nd4|rbjrp3ca|linrc649|pgcl6ej4|gctlj659|prkc6r5c|", // 专业名称 "professionCode": "jcj7q1o2|coil7s13|", // 专业代码 "professionDesc": "", "chooseSubject": "", "planNum": "kscoq2re7a|", "cost": "gittc717|c7tspk12|mnchh712|kc7grm12|", // 学费 "learnYear": "c7kglr16|", // 学年制 "remarks": "kioct6a9|【色】|【盲】|" // 备注 } ] } ] } ] }
- 存储:每个省份都有一个对应的文件夹,每个省份的数据按每个大类去存储,如提前批本科作为一个
json文件。
- 用
parse-util解密,跟接口响应数据的存储一样,每个省份都有一个对应的文件夹,每个省份的数据按每个大类去存储,如提前批本科作为一个json文件
- request
- url: https://ia-pv4y.youzy.cn/scorelines/pcl
- method: get
- params
- p: 省份信息
let encryptP = common.youzyEpt(p)
- tcode: 省份id加密信息,关键参数
tcode = common.youzyept({ provinceid: id })
- toUrl: 固定参数,'/scorelines/pcl'
- response
- data: 爬取的网页代码
- 所有的省份的结果都存在一个叫
score-lines.json的文件
每个大学在每个省份都有一个对应的 ucode,使用这个ucode,可以查询该大学在该省份的一些信息,如该大学在该省份的专业分数线,院校分数线
- request
- url: https://ia-pv4y.youzy.cn/Data/ScoreLines/UCodes/QueryList?p=abc
- method: post
- params
- data:
common.youzyEpt()加密queryObj后的字符串
queryObj = { provinceId: provinceId, collegeId: cid }
- data:
- response
- 返回一个数组,使用下面的步骤可以拼接出正确的 ucode
const data = res.data.result if (data.length !== 0) { ucode = data[0].uCodeNum data.forEach(function (r) { var uCodeNumArr = r.uCodeNum.split('_').reverse() if (uCodeNumArr[0] == '0' && uCodeNumArr[1] == '0') { uCode = r.uCodeNum } }) }
- 返回一个数组,使用下面的步骤可以拼接出正确的 ucode
- request
- url: https://www.youzy.cn/tzy/search/colleges/collegeList
- method: get
- header
- Cookie: 需要在
cookie中加入随便一个省份的信息,不然会导致接口一直发生重定向去设置省份信息。
'Cookie': 'Youzy2CCurrentProvince=%7B%22provinceId%22%3A848%2C%22provinceName%22%3A%22%E6%B2%B3%E5%8D%97%22%2C%22isGaokaoVersion%22%3Afalse%7D;'
- Cookie: 需要在
- params
- page: 页面索引
- response
- data: 爬取的网页源代码
- 所有的大学结果都存在一个叫
colleges.json的文件。
- request
- url: http://ia-pv4y.youzy.cn/Data/ScoreLines/Fractions/Colleges/Query?p=abc
- method: post
- data: 加密参数 encryptP
encryptP = common.youzyEpt({ provinceNumId: id, ucode: uCode // 每个大学在每个省份都一个 ucode })
- response
year: 2019 // 从 2012 到 2019 course: 0 // 1 代表文科,0 代表理科 batch: 1 // 批次,1 应该是第一批 batchName: "本一批" // 批次名称 uCode: "41_838_0_0" // 该大学再该省份的 ucode chooseLevel: "" // 不清楚 lineDiff: 182 // 不清楚 minScore: "ki6oifp732|lofioc6ra6|ssci2eqs7a|" // 最低分 avgScore: 0 maxScore: 0 lowSort: "s7ss2reof1|p6pf7oo3p2|" // 最低位次 maxSort: 0 // 最高位次 enterNum: "l7dkip3qae|se7loqlf11|" // 录取人数 countOfZJZY: 0 prvControlLines: 502 //不清楚
- 存储:每个省份的大学都放在同一个文件中,以省份的名字作为文件名
- 存储:每个省份的大学都放在同一个文件中,以省份的名字作为文件名
-
request
- url: http://ia-pv4y.youzy.cn/Data/ScoreLines/Fractions/Professions/Query?p=abc
- method: post
- params
- data:
common.youzyEpt()加密queryObj后的字符串
queryObj = { uCode: uCode, // 每个大学再每个省份对应的 ucode // batch: 0, // 哪个批次,因为这里需要一次获取全部数据,所以这个参数可以不要 courseType: courseType, // 文科理科,0 是理科,1 是文科 yearFrom: yearFrom, // 这个接口的时间是一个区间,查询出 [from ,to] 区间的数据,可以查具体某一年的数据,如 [2019, 2019],也可以查出一个时间段的数据,如 [2012, 2018] yearTo: yearTo }
- data:
-
response
year: 2018 courseType: 1 batch: 1 batchName: "本一批" uCode: "41_838_0_0" chooseLevel: "" lineDiff: 129 majorCode: "140109" // 专业代码,猜测应该是用来查询某个专业具体信息用的关键字段 professionName: "" // 专业名称 professionCode: "srocr712|cn7hoq13|" // 专业代码,页面显示用的 remarks: null maxScore: "nhp6f7np32|aogaj86hoe|io6lnfj732|" minScore: "rn6flr7g32|nparska86e|r6tfnmq732|" avgScore: "6hlpfls732|morpaka86e|o6rrf73kq2|" lowSort: "c1ttm5fmj9|qqkao8hf2e|" // 该专业的最低排位 maxSort: 0 enterNum: "nncjs1j5f9|" // 录取人数 countOfZJZY: 0
-
存储:每个大学的
cid作为文件名,将该大学各专业在各省份的招生情况保存起来,如838.json就是北京大学(cid = 838)的专业信息
- 解析:每个大学的
cid作为文件名,将该大学各专业在各省份的招生情况保存起来,如838.json就是北京大学(cid = 838)的专业信息