按学科分类【中图分类】

共计三十余万条科技报告数据

爬取的网址:https://www.nstrs.cn/kjbg/navigation

!!!

如果要完整地跑起来代码,需要先看一下我的这篇博客,完成IP代理池的相关配置:

https://www.cnblogs.com/rainbow-1/p/16725503.html

!!!


分析网站数据来源可以发现,是使用的post方式的请求,且参数列表如下:

那么我们需要做的就是模拟这个请求,同时需要带上我们自定义的参数,这里面需要的其实一个就是页码pageNo,另一个是分类,如下图:

parms = {
"pageNo": i,
"competentOrg": "",
"jihuaId": "",
"fieldCode": "",
"classification": name, # 修改
"kjbgRegion": "",
"kjbgType": "",
"grade": ""
}

简单说一下我都做了什么,首先是配置是IP代理池,存在redis数据库,每次【设置了随机延迟时间】随机取出一个进行访问。

其次使用了随机UserAgent请求头。

爬虫是直接使用post请求,携带参数抓获返回的json数据做解析并存入mysql数据库。


下面是代码:

爬虫方法report_crawler

也就是你需要直接运行的方法。

我这部分是从"社会科学总论"这个分类开始爬的,前面那些如果需要爬,就直接改pageList页码列表、nameList名称列表、tableList数据库表列表就可以【切记是一 一对应的!】

import json
import random
from time import sleep import requests
from fake_useragent import UserAgent from report_data.into_mysql import insert_mysql
from report_data.ip_redis import my_redis """
post方法参数
params:字典或字节序列,作为参数增加到链接中
data:字典,字节序列或文件对象,作为请求的内容
json:JSON格式的数据,作为Request的内容
headers:字典,HTTP定制头(模拟浏览器进行访问)
cookies:字典或CpplieJar,Request中的cookie
auth:元祖,支持HTTP认证功能
files:字典类型,传输文件
timeout:设定超时时间,秒为单位
proxies:字典类型,设定访问代理服务器,可以增加登陆认证
allow_redirects:True//False,默认为True,重定向开关
stream:True/False,默认为True,获取内容立即下载开关
verify:True/False,默认为True,认证SSL证书开关
cert:本地SSL证书路径
"""
# 页码pageList
# 分类名称参数列表 nameList
#
def get_report(page,name,tableName):
# ------------------------------ 修改页码
for i in range(1,page):
print("---------------------------------")
ua = UserAgent()
print("【随机 UserAgent:】" + ua.random) # 随机产生headers
temp_headers = ua.random
# --------------------------------------
test_redis = my_redis()
temp_proxy = test_redis.get_ip()
print("【随机 IP:】" + temp_proxy)
url="https://www.nstrs.cn/rest/kjbg/wfKjbg/list"
# url2 = "https://www.nstrs.cn/rest/kjbg/wfKjbg/list?pageNo=2&competentOrg=&jihuaId=&fieldCode=&classification=医药、卫生&kjbgRegion=&kjbgType=&grade="
parms = {
"pageNo": i,
"competentOrg": "",
"jihuaId": "",
"fieldCode": "",
"classification": name, # 修改
"kjbgRegion": "",
"kjbgType": "",
"grade": ""
} other_parms={
'User-Agent': temp_headers,
'https': 'http://'+temp_proxy,
'http': 'http://'+temp_proxy
}
sleeptime = random.uniform(0, 0.7)
sleep(sleeptime)
# print(url)
response = requests.post(url, parms, other_parms)
response.encoding='utf8'
print(response.text+'\n')
response_data = response.text # 返回数据
json_data = json.loads(response_data) # 封装字典
res_list_data = json_data['RESULT']['list'] # 一页 长度为10的list [{ },{ },{ } ... { }] len=10 """
重新构建一个 list [{ }]
"""
for item in res_list_data:
insert_mysql(item,name,tableName)
return if __name__ == '__main__':
# 页码 pageList []
pageList = [788,779,656,584,573,510,440,361,
315,226,224,220,155,112,112,
87,53,50,39,33,18,12,5,4,2,2,2,2] nameList = [
"社会科学总论",
"环境科学、安全科学",
"建筑科学",
"轻工业、手工业",
"数理科学与化学",
"能源与动力工程",
"电工技术",
"矿业工程",
"经济",
"文化、科学、教育、体育",
"水利工程",
"交通运输",
"自然科学总论",
"石油、天然气工业",
"冶金工业",
"武器工业",
"航空、航天",
"哲学、宗教",
"原子能技术",
"历史、地理",
"政治、法律",
"艺术",
"语言、文字",
"军事",
"综合性图书",
"文学",
"语言、文学",
"mks主义、ln主义、mzd思想、dxp理论"
] tableList = ["tech_c","tech_x","tech_tu","tech_ts","tech_o","tech_tk","tech_tm",
"tech_td","tech_f","tech_g","tech_tv","tech_u",
"tech_n","tech_te","tech_tf","tech_tj","tech_v","tech_b","tech_tl",
"tech_k","tech_d","tech_j","tech_h","tech_e","tech_z","tech_i","tech_i","tech_a"]
for i in range(0,len(tableList)):
get_report(pageList[i],nameList[i],tableList[i])

目录方法category

返回一个中图分类号对应的名称

# 用以返回中图分类号
def get_code(key):
code_dict = {
"医药、卫生":"R",
"一般工业技术":"TB",
"生物科学":"Q",
"数理科学和化学":"O",
"农业科学":"S",
"工业技术":"T",
"自动化技术、计算机技术":"TP",
"天文学、地球科学":"P",
"无线电电子学、电信技术":"TN",
"金属学与金属工艺":"TG",
"机械、仪表工业":"TH",
"化学工业":"TQ",
"社会科学总论":"C",
"环境科学、安全科学":"X",
"建筑科学":"TU",
"轻工业、手工业":"TS",
"数理科学与化学":"O",
"能源与动力工程":"TK",
"电工技术":"TM",
"矿业工程":"TD",
"经济":"F",
"文化、科学、教育、体育":"G",
"水利工程":"TV",
"交通运输":"U",
"自然科学总论":"N",
"石油、天然气工业":"TE",
"冶金工业":"TF",
"武器工业":"TJ",
"航空、航天":"V",
"哲学、宗教":"B",
"原子能技术":"TL",
"历史、地理":"K",
"政治、法律":"D",
"艺术":"J",
"语言、文字":"H",
"军事":"E",
"综合性图书":"Z",
"文学":"I",
"语言、文学":"I",
"mks主义、ln主义、mzd思想、dxp理论":"A",
}
res = code_dict.get(key)
return res
if __name__ == '__main__':
data = get_code("工业技术")
print(data)

user_agent方法

返回随机headers

from fake_useragent import UserAgent   # 下载:pip install fake-useragent
import requests ua = UserAgent() # 实例化,需要联网但是网站不太稳定-可能耗时会长一些
print(ua.random) # 随机产生
headers = {
'User-Agent': ua.random # 伪装
} # 请求
if __name__ == '__main__':
url = 'https://www.baidu.com/'
response = requests.get(url, headers=headers ,proxies={"http":"117.136.27.43"})
print(response.status_code)

ip_redis方法

从redis数据库取出一个ip并返回(前3000个随机一个,降序排列)

import random

import redis

class my_redis:

    def get_ip(self):
r = redis.Redis(host='127.0.0.1', port=6379, db=0,decode_responses=True)
my_redis_data = r.zrange("proxies:universal",1,3000,True)
return random.choice(my_redis_data)
# print(len(my_redis_data)) if __name__ == '__main__':
test_redis=my_redis()
data=test_redis.get_ip()
print(data)

into_mysql方法

存入mysql数据库的方法

#连接数据库  获取游标
import pymysql
from report_data.category import get_code def get_conn():
"""
:return: 连接,游标
"""
# 创建连接
conn = pymysql.connect(host="127.0.0.1",
user="root",
password="reliable",
db="tech",
charset="utf8mb4")
# 创建游标
cursor = conn.cursor() # 执行完毕返回的结果集默认以元组显示
if ((conn != None) & (cursor != None)):
print("数据库连接成功 ...")
else:
print("数据库连接失败!")
return conn, cursor
#关闭数据库连接和游标
def close_conn(conn, cursor):
if cursor:
cursor.close()
if conn:
conn.close()
return 1
# 数据表名
# 中图分类名
def insert_mysql(data,name,tableName):
print(data['title']) id=data['id']
title=data['title']
alternativeTitle=data['alternativeTitle']
creator=data['creator']
abstractEn=data['abstractEn']
keywordsEn=data['keywordsEn']
abstractCn=data['abstractCn']
keywordsCn=data['keywordsCn']
creatOrorganization=data['creatOrorganization']
prepareOrganization=data['prepareOrganization']
publicDate=data['publicDate']
createTime=data['createTime']
projectName=data['projectName']
competentOrg=data['competentOrg']
projectSubjectName=data['projectSubjectName']
projectSubjectId=data['projectSubjectId']
#------------------------------
classification=name # 修改
#------------------------------
classificationCode=get_code(classification) # 需要调用get_code(name)获取
responsiblePerson = data['responsiblePerson']
supportChannel = data['supportChannel']
undertakeOrg = data['undertakeOrg']
kjbgSource = data['kjbgSource']
proposalDate = data['proposalDate']
submittedDate = data['submittedDate']
kjbgRegion = data['kjbgRegion']
collectionDate = data['collectionDate']
collectionNumber = data['collectionNumber']
fieldCode = data['fieldCode']
fieldId = data['fieldId']
kjbgQWAddress = data['kjbgQWAddress']
isNewRecord = data['isNewRecord']
sourceUrl = "https://www.nstrs.cn/kjbg/detail?id="+id # 需要自己拼 https://www.nstrs.cn/kjbg/detail?id= conn, cursor = get_conn()
# ------------------------------ 修改表名
sql = "insert into `"+tableName+"` (id,title,alternativeTitle,creator,abstractEn," \
"keywordsEn,abstractCn,keywordsCn,creatOrorganization,prepareOrganization," \
"publicDate,createTime,projectName,competentOrg,projectSubjectName," \
"projectSubjectId,classification,classificationCode,responsiblePerson,supportChannel," \
"undertakeOrg,kjbgSource,proposalDate,submittedDate,kjbgRegion," \
"collectionDate,collectionNumber,fieldCode,fieldId,kjbgQWAddress," \
"isNewRecord,sourceUrl) 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,%s,%s,%s,%s,%s,%s,%s,%s)"
try:
try:
cursor.execute(sql, [id,title,alternativeTitle,creator,abstractEn,
keywordsEn,abstractCn,keywordsCn,creatOrorganization,prepareOrganization,
publicDate,createTime,projectName,competentOrg,projectSubjectName,
projectSubjectId,classification,classificationCode,responsiblePerson,supportChannel,
undertakeOrg,kjbgSource,proposalDate,submittedDate,kjbgRegion,
collectionDate,collectionNumber,fieldCode,fieldId,kjbgQWAddress,isNewRecord,sourceUrl])
except pymysql.err.IntegrityError:
print("主键冲突!")
conn.commit() # 提交事务 update delete insert操作
except pymysql.err.IntegrityError:
print("error!")
finally:
close_conn(conn, cursor)
return 1 if __name__ == '__main__':
print()

最终爬取三十多万条科技报告,按中图分类建立了mysql数据表,分表存储不同分类的数据。

【其中的数理科学和化学,数理科学与化学这两个分类做了合并,合并为数理科学和化学类,属O】

【语言、文学和文学做了合并,同属 I 文学类】

附几张结果图:

最后说一下数据表结构:

/*
Navicat MySQL Data Transfer Source Server : reliable
Source Server Version : 80013
Source Host : localhost:3306
Source Database : tech Target Server Type : MYSQL
Target Server Version : 80013
File Encoding : 65001 Date: 2022-09-24 13:54:05
*/ SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Table structure for tech_o
-- ----------------------------
DROP TABLE IF EXISTS `tech_o`;
CREATE TABLE `tech_o` (
`id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'ID',
`title` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '中文标题',
`alternativeTitle` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '英文标题',
`creator` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '作者',
`abstractEn` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '英文摘要',
`keywordsEn` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '英文关键字',
`abstractCn` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '中文摘要',
`keywordsCn` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '中文关键字',
`creatOrorganization` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '创建者组织',
`prepareOrganization` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '预备组织',
`publicDate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公布时间',
`createTime` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '编制时间',
`projectName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目名称',
`competentOrg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目地址',
`projectSubjectName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目主题名称',
`projectSubjectId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目主题ID',
`classification` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '中图分类名称',
`classificationCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '中图分类号',
`responsiblePerson` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '负责人',
`supportChannel` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '主办方',
`undertakeOrg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '承办方',
`kjbgSource` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '科技报告来源单位',
`proposalDate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '提议时间',
`submittedDate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '提交时间',
`kjbgRegion` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '科技报告所属行政区划',
`collectionDate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '收集时间',
`collectionNumber` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '收集编号',
`fieldCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '领域代码',
`fieldId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '领域ID',
`kjbgQWAddress` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '报告链接',
`isNewRecord` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否新记录',
`sourceUrl` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '国家科技报告服务系统收录链接',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

后续数据处理参考:科技报告数据语料处理(关键词、中图分类名称)【https://www.cnblogs.com/rainbow-1/p/16801120.html】

如果需要获取这部分数据,可关注我的微信公众号【靠谱杨阅读人生】,回复 “科技报告” 获取下载链接。

python爬虫爬取科技报告数据,共计40余万条(来自国家科技报告服务系统)的更多相关文章

  1. python爬虫-爬取豆瓣电影数据

    #!/usr/bin/python# coding=utf-8# 作者 :Y0010026# 创建时间 :2018/12/16 16:27# 文件 :spider_05.py# IDE :PyChar ...

  2. python爬虫—爬取百度百科数据

    爬虫框架:开发平台 centos6.7 根据慕课网爬虫教程编写代码 片区百度百科url,标题,内容 分为4个模块:html_downloader.py 下载器 html_outputer.py 爬取数 ...

  3. python爬虫爬取赶集网数据

    一.创建项目 scrapy startproject putu 二.创建spider文件 scrapy genspider  patubole patubole.com   三.利用chrome浏览器 ...

  4. 用Python爬虫爬取广州大学教务系统的成绩(内网访问)

    用Python爬虫爬取广州大学教务系统的成绩(内网访问) 在进行爬取前,首先要了解: 1.什么是CSS选择器? 每一条css样式定义由两部分组成,形式如下: [code] 选择器{样式} [/code ...

  5. 使用Python爬虫爬取网络美女图片

    代码地址如下:http://www.demodashi.com/demo/13500.html 准备工作 安装python3.6 略 安装requests库(用于请求静态页面) pip install ...

  6. Python爬虫|爬取喜马拉雅音频

    "GOOD Python爬虫|爬取喜马拉雅音频 喜马拉雅是知名的专业的音频分享平台,用户规模突破4.8亿,汇集了有声小说,有声读物,儿童睡前故事,相声小品等数亿条音频,成为国内发展最快.规模 ...

  7. Python爬虫爬取全书网小说,程序源码+程序详细分析

    Python爬虫爬取全书网小说教程 第一步:打开谷歌浏览器,搜索全书网,然后再点击你想下载的小说,进入图一页面后点击F12选择Network,如果没有内容按F5刷新一下 点击Network之后出现如下 ...

  8. python爬虫—爬取英文名以及正则表达式的介绍

    python爬虫—爬取英文名以及正则表达式的介绍 爬取英文名: 一.  爬虫模块详细设计 (1)整体思路 对于本次爬取英文名数据的爬虫实现,我的思路是先将A-Z所有英文名的连接爬取出来,保存在一个cs ...

  9. 一个简单的python爬虫,爬取知乎

    一个简单的python爬虫,爬取知乎 主要实现 爬取一个收藏夹 里 所有问题答案下的 图片 文字信息暂未收录,可自行实现,比图片更简单 具体代码里有详细注释,请自行阅读 项目源码: # -*- cod ...

  10. python爬虫-爬取百度图片

    python爬虫-爬取百度图片(转) #!/usr/bin/python# coding=utf-8# 作者 :Y0010026# 创建时间 :2018/12/16 16:16# 文件 :spider ...

随机推荐

  1. sentry 在加载模块时闪退

    这是一个很久之前的问题了,今天记录一下,以便遇到同样问题的同学能够看到此文章 崩溃环境: 目前仅收到 windows 7 的部分用户反馈,在程序启动时发生闪退 问题分析: 查看用户提供的日志,可以看见 ...

  2. win32-GetActiveWindow和GetForegroundWindow

    最近被这两个api搞得有点晕,故查阅了相关的资料. 这篇文章解释的很好:https://devblogs.microsoft.com/oldnewthing/20081006-00/?p=20643 ...

  3. Excel 求和函数结果一直为零

    参考资料:Excel表格求和结果总是0怎么办 用SUMIFS函数求和,结果都是零 错误原因: 1.单元列数据格式设置错误,参考资料一 2.数据中含有空格或者回车键或者隐藏字符,参考资料二 解决方法: ...

  4. 【Azure Service Fabric】关于Service Fabric的相关问题

    问题一:Service Fabric 是否支持Private Link? 在Azure Private Endpoint文档中,罗列出了 Azure 上支持 Private Link 的服务.Serv ...

  5. 【Azure 应用服务】App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢?

    问题描述 App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢? 问题解答 答案是可以的,Azure App Service .NE ...

  6. 【Azure 应用服务】Azure App Service能否使用Storage Account File Share

    问题描述 Azure App Service能否使用Storage Account File Share? 问题回答 如果部署的App Service为Linux环境,可以直接使用Mount stor ...

  7. 【应用服务 App Service】App Service For Linux 中如何挂载一个共享文件夹呢? Mount Azure Storage Account File Share

    问题描述 使用Linux作为服务器运行Web App时,如何将 Storage Account 作为本地共享装载到 App Service for  Linux / Container 中的应用呢? ...

  8. 浅入 ABP 系列(6):数据库配置

    浅入 ABP 系列(6):数据库配置 版权护体作者:痴者工良,微信公众号转载文章需要 <NCC开源社区>同意. 目录 浅入 ABP 系列(6):数据库配置 创建标准的 EFCore 数据库 ...

  9. 基于 Nebula Graph 构建百亿关系知识图谱实践

    本文首发于 Nebula Graph Community 公众号 一.项目背景 微澜是一款用于查询技术.行业.企业.科研机构.学科及其关系的知识图谱应用,其中包含着百亿级的关系和数十亿级的实体,为了使 ...

  10. Android 安装手机程序有问题/点击runAPP 程序安装不了手机

    可以在 gradle.properties 里添加   android.injected.testOnly=false   点击同步  就可以运行了 如下: