按学科分类【中图分类】

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

爬取的网址: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. C++ 多线程的错误和如何避免(5)

    要记得对加锁的临界区解锁 前提:在多个线程共享一块资源或者数据时,我们需要加上互斥锁来保护临界区(否则出现数据未定义的行为) 问题:我们往往在写了很多代码之后忘记 unlock 互斥锁,那么等待该资源 ...

  2. Hexo - 搭建个人博客的bug集合

    按照很多视频教程进行操作,发现到hexo d这一步后,无法部署到github远端. 目前的解决方法: npm un hexo-deployer-git npm i hexojs/hexo-deploy ...

  3. js结合canvas画任意多边形

    实现六边形 // html <canvas></canvas> // js const canvas = document.querySelector("canvas ...

  4. LayUI框架应用常见问题

    https://layui.itze.cn/index.html LayUI框架文档主页 获取URL参数 诸如表格中的"编辑","详情"工具按钮,需要在弹出层页 ...

  5. React 组件懒加载

    只有不断学习和成长,才能适应这个快速变化的世界. 1. 懒加载 1.1 React 懒加载 React 中懒加载 Lazy 与 Suspense 需要搭配使用. React.lazy 定义: Reac ...

  6. HashMap源码窥探

    目录 前言 HashMap的数据结构 HashMap的put方法 HashMap的get方法 HashMap的初始化 HashMap的containsKey方法 HashMap的putAll方法 Ha ...

  7. 【Azure Developer】如何通过Azure REST API 获取到虚拟机(VM)所使用的公共IP地址信息

    问题描述 如何通过Azure REST API 获取到虚拟机(VM)所使用的公共IP地址信息 问题解答 由于直接获取到的虚拟机信息(Virtual Machines - Get)中,并不会包含虚拟机的 ...

  8. linux虚拟机初始配置

    1- CentOS7配置静态IP地址: iface="网络接口名"cd /etc/sysconfig/network-scripts/; sed -i 's/^/#/' ifcfg ...

  9. SpringCloud Hystrix断路器的基本使用

    官网资料: https://github.com/Netflix/Hystrix/wiki/How-To-Use 1. 服务雪崩 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系, ...

  10. SQL之基本查询

    提纲 记录查询 使用列别名 查询语句执行顺序 数据分页 子句执行顺序 结果集排序 PS: 排序注意 多个排序字段 子句执行顺序 结果集去除重复数据 注意: 条件查询 比较运算符 注意 子句执行顺序