python数据爬虫项目

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")


四、数据结果展示

在这里插入图片描述

新手上路,多多指教

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值