前言

开发一款app,最重要的一部分就是数据了,现在也是大数据时代,数据信息非常庞大,同时数据对app来说,是不可或缺的一部分。在我们这个app当中,由于是查询类app,因此数据采集非常重要,至关重要的组成部分,因此,本篇着重介绍如何通过爬虫来获取数据并存入数据库。

网站分析

首先我们打开高校网站:中国教育在线

iOS 获取当前APP存储空间_mysql


当时我在看这个网页的源码时意外发现,该网站的开发人员竟然直接将高校数据以json的方式存储,没有任何其他的加密操作,真是简直了。。。

我们随便选择一个栏目,以查高校为例子,点击顶部的查高校 tab,进入到二级页面,我们打开chrome的调试工具控制台,

iOS 获取当前APP存储空间_mysql_02


打卡XHR那一列,然后查看左侧的网络返回数据,我们会发现点击查高校请求的API接口就是左侧圈起来的那个,右侧是我们请求到的返回数据。

iOS 获取当前APP存储空间_数据库_03

我们把左侧的请求URL ccopy出来,分析一下他的内容:

https://api.eol.cn/gkcx/api/?access_token=&admissions=¢ral=&department=&dual_class=&f211=&f985=&is_dual_class=&keyword=&page=1&province_id=&request_type=1&school_type=&signsafe=&size=20&sort=view_total&type=&uri=apigkcx/api/school/hotlists

我们仔细分析一下上面的请求URL,应该很好理解,我们着重分析一些重要的请求参数:

请求域名:  https://api.eol.cn/gkcx/api/?
请求的token:  access_token
是否是211:  f211
是否是985:  f985
分页查询:   page
关键字搜索:  keyword
省份id:    province_id
院校类别:  school_type
办学类型:   department
分页每次查询的大小:  size
。。。

至于这些请求参数的值是哪些,你可以对照着上面的筛选条件进行查看,你每点击一个对应的请求条件,下面的请求URL就会将参数的值带入,通过这种方式你就可以将数据请求下来。

iOS 获取当前APP存储空间_数据库_04


另外需要注意的是,查高校是带分页的,所以要注意page这个参数的取值范围,同时要注意size

python爬虫

上面那种方式是我们分析网页得到的数据,我们不可能通过手动复制的方式来获取这些数据,因此需要我们借助自动化脚本来获取这些数据。我们可以借助python这门语言,天然的处理数据最拿手。

使用python爬取网页的数据的话,我们需要将数据存储到mysql中,因此第一步就是在数据库中新建表,具体的操作方式可以Google一下,也可以查询前一篇我写好的文章来操作《开源app-从0到1实现(二)项目运行》。假设我们已经在mysql中新建好了高校表:top_university_school_list

第一步连接mysql

try:
    conn = pymysql.connect(
        # mysql本机连接 或者写127.0.0.1也可以连接远程数据库
        host="localhost",
        # 数据库用户名称
        user="数据库用户名称",
        # 密码
        passwd="数据库密码",
        # 连接的数据库名字
        db="top_university",
        # 端口
        port=3306
    )
except pymysql.Error as e:
    print("连接失败:%s" % e)

第二步发起请求

发起请求的话就要用到python的requests框架,python 详细用法自行Google

url = "https://api.eol.cn/gkcx/api/?access_token=&admissions=¢ral=&department=&dual_class=&f211=&f985=&is_dual_class=&keyword=&page=" + str(
        id) + "&province_id=&request_type=1&school_type=&signsafe=&size=20&sort=view_total&type=&uri=apigkcx/api/school/hotlists"
    infoes = json.loads(get_html(url))
    length = len(infoes['data']['item'])

第三步存mysql

获取到接口返回的数据后,我们通过json来解析,解析成功之后就需要进行数据库插入操作了:

for i in range(length):
        result = []
        try:
            name = infoes['data']['item'][i]['name']
            result.append(infoes['data']['item'][i]['address'])
            result.append(infoes['data']['item'][i]['belong'])
            result.append(infoes['data']['item'][i]['city_id'])
            result.append(infoes['data']['item'][i]['city_name'])
            result.append(infoes['data']['item'][i]['code_enroll'])
            result.append(infoes['data']['item'][i]['colleges_level'])
            result.append(infoes['data']['item'][i]['department'])
            result.append(infoes['data']['item'][i]['dual_class'])
            result.append(infoes['data']['item'][i]['dual_class_name'])
            result.append(infoes['data']['item'][i]['f211'])
            result.append(infoes['data']['item'][i]['f985'])
            result.append(infoes['data']['item'][i]['level'])
            result.append(infoes['data']['item'][i]['level_name'])
            result.append(infoes['data']['item'][i]['is_top'])
            result.append(infoes['data']['item'][i]['name'])
            result.append(infoes['data']['item'][i]['nature_name'])
            result.append(infoes['data']['item'][i]['nature'])
            result.append(infoes['data']['item'][i]['province_id'])
            result.append(infoes['data']['item'][i]['province_name'])
            result.append(infoes['data']['item'][i]['publish_id'])
            # result.append(infoes['data']['item'][i]['rank'])
            # result.append(infoes['data']['item'][i]['rank_type'])
            result.append(infoes['data']['item'][i]['school_id'])
            result.append(infoes['data']['item'][i]['school_type'])
            result.append(infoes['data']['item'][i]['type'])
            result.append(infoes['data']['item'][i]['type_name'])
            sql = "insert into top_university_school_list_temp(address,belong,city_id,city_name,code_enroll,colleges_level,department,dual_class,dual_class_name,f211,f985,level,level_name,is_top,name,nature_name,nature,province_id,province_name,publish_id,school_id,school_type,type,type_name)values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
            cursor.execute(sql, (result))
            print("***********正在写入" + name)
        except Exception as e:
            print(e)

需要注意的是,高校数据很大,如果我们一个一个去爬取的话非常耗时,这个时候我们便可以开启多线程去同时爬取,提高效率。

第四步多线程爬取

pool = Pool(5)
    origin_num = [x for x in range(1, 149)]
    # origin_num = [x for x in range(1, 2)]
    try:
        pool.map(insert_mysql, origin_num)
    except Exception as e:
        print(e)

iOS 获取当前APP存储空间_数据_05

源码