python数据爬虫项目
作者:YRH
时间:2020/9/26
新手上路,如果有写的不好的请多多指教,多多包涵
前些天在一个学习群中有位老哥发布了一个项目,当时抱着满满的信心想去尝试一下,可惜手慢了,抢不到,最后只拿到了项目的任务之间去练习,感觉该项目还不错,所以就发布到博客上来,让大家一起学习学习
一、任务清单
项目名称:国家自然科学基金大数据知识管理服务门户爬取项目
爬取内容:爬取内容:资助项目(561914项)
爬取链接:HTTP://KD.NSFC.GOV.CN/BASEQUERY/SUPPORTQUERY
第一阶段:
1、 需要对申请代码、资助类别和批准年度进行筛选。
2、 爬取信息:
项目名称、批准号、项目类别、项目负责人、批准年度、资助金飞、依托单位、起止年月、申请代码、关键词、研究成果、结题项目
第二阶段:爬取完整的项目信息
1、 根据批准号从链接爬取
2、 需要爬取的信息
二、网页结构分析
1、路线选择
刚开始看到网页是第一时间想到的是使用selenium自动化爬取,但是通过网络请求方式察觉到该网站的数据获取方式是post请求的
所以只有利用post请求方式将传表单到http://kd.nsfc.gov.cn/baseQuery/data/supportQueryResultsDataForNew上,就能获取到数据。
所以最后选择了requests路线进行爬取
2、表单上传结构分析
从网页界面可以看出,想要提取信息必须上传三个参数,分别是申请代码、资助类型和批准年度。这三个所对应的是键是code、projectType和ratifyYear,所以这三个是回去数据各项类型必传的参数。但是当我在访问是一直错误,访问不了,然后就尝试多加几个参数进去,最后发现queryType: "input"这个参数必须上传,否则会报错
在传入参数前必须先看一下参数类型是什么,在Requests Headers中有一个参数Content-Type: application/json,可以看得出传入的参数是json类型的,所有参数必须先转为json类型
三、数据爬取代码
因为该网站数据比较多,所以我将数据保存至MySQL数据库在,如果想执行我代码需要先将访问数据库的代码给修改一下
数据比较多,所以我只爬取了2019年份的数据,没爬全
# -*- coding: utf-8 -*-
# Author : YRH
# Data :
# Project :
# Tool : PyCharm
import requests
from fake_useragent import UserAgent
import random
import json
import xlwt
import time
import threading
import time
ua = UserAgent()
def join_url(year):
da = []
# 项目类型代码
projectType = ["218", "220", "339", "579", "630", "631", "649"]
# 提取申请代码
response = requests.get("http://kd.nsfc.gov.cn/common/data/fieldCode")
response.encoding = response.apparent_encoding
data = eval(response.text.replace("\xa0", "").replace("\u200d", ""))
data = data["data"]
for y in year:
for p in projectType:
for code in data:
name = code["name"]
code = code["code"]
if len(code) <= 1:
continue
da.append({"year": str(y), "name": name, "code": code, "project": p})
return da
def spider(payload, data_list):
try:
url = "http://kd.nsfc.gov.cn/baseQuery/data/supportQueryResultsData"
headers = {
"User-Agent": ua.random,
"Content-Type": "application/json"
}
data = {
"code": payload["code"], "conclusionYear": payload["year"], "projectType": payload["project"],
"queryType": "input",
"complete": "true", "pageNum": 0,
}
response = requests.post(url, data=json.dumps(data), headers=headers)
response.encoding = response.apparent_encoding
text = response.text
text = text.replace("\ue06d", "").replace("\u2022", "").replace("\xf6", "")
da = eval(text)
jiexi(da, data_list)
except Exception as E:
print(E)
def jiexi(resultsData, data_list):
try:
result = resultsData["data"]["resultsData"]
for data in result:
projectName = data[1]
approvalN = data[2]
projectType = data[3]
projectLeader = data[5]
relyingUnit = data[4]
year = data[7]
keyword = data[8]
data_dict = {"项目名称": projectName,
"项目批准号": approvalN,
"项目类型": projectType,
"项目负责人": projectLeader,
"依托单位": relyingUnit,
"批准年度": year,
"关键词": keyword}
print(data_dict)
data_list.append(data_dict)
except Exception as E:
print(E)
def run(payload, data_list):
print(payload)
# time.sleep(0.1)
if __name__ == '__main__':
all_data = []
# 爬取的项目年份
year = [2019]
data = join_url(year)
# 单任务执行
# for d in data:
# try:
# spider(d, all_data)
# except Exception as e:
# print(e)
# 多任务执行
for d in data:
try:
spider_thread = threading.Thread(target=spider, kwargs={"payload": d, "data_list": all_data})
spider_thread.start()
except Exception as E:
print(E)
spider_thread.join()
# 数据保存
workbook = xlwt.Workbook(encoding="utf-8")
worksheet = workbook.add_sheet("sheet1")
head = ["项目名称", "项目类型", "批准年度", "项目批准号", "项目负责人", "依托单位", "关键词"]
for i in range(7):
worksheet.write(0, i, head[i])
row = 1
for i in all_data:
for j in range(0, len(head)):
worksheet.write(row, j, i[head[j]])
row += 1
workbook.save("结题项目数据.xls")
四、数据结果展示
新手上路,多多指教