准备工具

  • 火车采集器
  • python编辑器

火车采集器爬取数据

1)准备好火车采集器和spyder

2)分析网页来确定爬取的流程:先用火车采集器把学校的省份、学校名字、专业页面的url爬取下来,然后用python爬取具体的专业内容。(原因:采集具体专业的时候不知道怎么用火车采集器实现js链接的采集,于是用python代码来实现)

3)火车采集器部分:
a)起始网址添加

图一

发现每一页start后面的数字加20,于是可以像下方图片一样配置。

图二

b)网址地址获取

图三

验证发现每一行有四个网址,我们只需要第一个,网址在<tbody></tbody>之间,用另外三个网址的共同特征过滤掉其它三个网址。

图四

c)采集结果

图五

共采集到了0级网址43个,1级网址851个,验证结果是正确的。

d)内容采集

分别设置省份、大学、网址三个标签,采用内容截取的方式从网站截取自己需要的内容。

图六

测试验证结果

图七

e)发布

由于免费版本就采取了txt的格式发布

图八

f)开始任务

采用10线程下载,采集成功

图九

图十

python爬取

主要思想:循环读取火车采集器采集下来的txt文件里的内容,一个文件为一个三个元素:省份、学校、网址的List,所有list再组成一个alllist。然后循环读取alllist中每个list的url,爬取url中的专业和科目,组成的对应有序list。然后组和,保存在csv文件即可。

Created on 20200106

@author: 陈良辉
"""
import requests
from bs4 import BeautifulSoup
import csv
#get_html函数用来解析网页源码
def get_html(url):
    res = requests.get(url)
    soup = BeautifulSoup(res.text,"lxml")
    return soup


def load_source(path):
    data = []
    file = open(path,'r',encoding='UTF-8') #用‘UTF-8’编码的格式打开
    file_data = file.readlines() #读所有行
    for row in file_data:
        data.append(row.replace('\n',''))     #循环读取,用''代替换行符,然后放在列表中
    return data

def get_alldata():
    alldata = []
    i = 0
    while(i < 851):
        path = 'D:\\mydata\\32_' + str(i) + '.txt' #将每一个txt的路径暂存在path中用来读取
        alldata.append(load_source(path)) #将所有的文件的内容调用函数读取,存为一个由省份、学校、url三个元素组成的list组成的两层list
        i+=1
    return alldata
def get_detail(url):
    j = 0
    data1 = []
    data3 = []
    alldata = []
    soup = get_html(url) 
    if 'tab-container zyk-zyfb-tab yxk-tab' in str(soup): #因为有些学校的专业为空,用该语句判断网页源码中是否存在下方的元素,然后再继续执行
        for sub in soup.find(attrs={'class':'tab-container zyk-zyfb-tab yxk-tab'}).find_all(attrs={'class':'tab-item js-tab'}):        
            data1.append(sub.string) #获取一个学校的所有专业,存在data1之中
        for obj in soup.find(attrs={'class':'tab-container zyk-zyfb-tab yxk-tab'}).find_all(attrs={'class':'clearfix'}):
            data2 = []
            for i in obj.find_all('li'): 
                if not(i.string is None): #因为存在个别学校网页的li标签中还有标签,所以用该语句判断是否还存在标签
                    a = i.string    #获取标签中的内容  
                    data2.append(a.replace('\r','').replace('\n','').replace(' ','')) #将获取的string中的换行符、空格、回车等并不必要的元素去除
                else:
                    obj2 = i.find(attrs={'target':'_blank'}).string #获取li标签中标签内的科目
                    data2.append(obj2.replace('\r','').replace('\n','').replace(' ',''))
            data3.append(data2) #将获取到的科目保存到data3
    else: #源码中不存在代码,则说明为空,则将data1和data3赋予空值
        data1.append('none')
        list1 = ['none']
        data3.append(list1)
    if data3[0] == []: #去除第一个空【】带来的影响
        del(data3[0])
    num = len(data1) #获取每一个学校专业的具体个数
    while(j<num):
        for i in data3[j]: #循环每个大类中的具体科目,刚好可以和专业相匹配
            data4 = []
            data4.append(data1[j]) #将第data[j]的专业放入data4
            data4.append(i) #将科目放在专业后面
            alldata.append(data4) #将组合好的专业和科目放入一个list
        j = j+1
    return alldata

def save_data():
    data = []
    num = 0
    num1 = 0
    data1 = get_alldata()
    for i in data1:
        url = i[2]
        data2 = get_detail(url) #获取一个学校的网址
        for j in data2:
            data3 = []
            data3 = i + j #将学校、省份、网址和专业、科目连接
            del(data3[2]) #去除不必要的网址
            data.append(data3)
        num = num + 1
        print('第%d个学校获取成功'%(num)) #将爬取过程可视化
    with open('D:/bigdata.csv', 'w', newline='') as csvfile: #创建打开csv文件
        writer = csv.writer(csvfile)
        for row in data: #将匹配好的List循环写入
            writer.writerow(row)
            num1 = num1 + 1
                       
if __name__ == "__main__":
    save_data()
Last modification:March 31, 2020
如果觉得我的文章对你有用,请随意赞赏