准备工具
- 火车采集器
- python编辑器
火车采集器爬取数据
1)准备好火车采集器和spyder
2)分析网页来确定爬取的流程:先用火车采集器把学校的省份、学校名字、专业页面的url爬取下来,然后用python爬取具体的专业内容。(原因:采集具体专业的时候不知道怎么用火车采集器实现js链接的采集,于是用python代码来实现)
3)火车采集器部分:
a)起始网址添加
发现每一页start后面的数字加20,于是可以像下方图片一样配置。
b)网址地址获取
验证发现每一行有四个网址,我们只需要第一个,网址在
之间,用另外三个网址的共同特征过滤掉其它三个网址。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()