scrapy抓取国家社科基金项目数据库
1.明确任务
目标网站:http://fz.people.com.cn/skygb/sk/index.php/Index/seach
抓取任务:抓取近五年某关键词(例如"能源"、”大数据“等)的搜索结果,抓取内容包括项目编号、项目名称、学科分类等十一个字段。
2.网站分析
利用Fiddler工具分析,输入关键词,指定年份后,点击搜索,针对有多页码搜索结果点击下一页,发现此过程共包括一个POST请求和一个GET请求;其中,指定关键词和年份点击搜索的过程为POST请求,点击下一页的过程为GET请求。
POST请求参数:
formdata = {
'xmname': '',
'xktype': '',
'xmtype': '',
'cglevel': '',
'cbdate ': '',
'cgxs': '',
'lxtime': '',
'ssxt': '',
'zyzw': '',
'dwtype': '',
'jxdata': '',
'szdq': '',
'pznum': '',
'cgname': '',
'jxnum': '',
'cbs': '',
'xmleader': '',
'hj': '',
'gzdw': '',
'zz': ''
}
POST请求目标URL:http://fz.people.com.cn/skygb/sk/index.php/Index/seach
GET请求只需要指定参数p即可,因此构造GET请求url为:
n_url = self.url + '?' + 'xmname={}&p={}'.format(formdata['xmname'], self.page)
其中,xmname为搜索关键词,p为第几页的页码。
3.代码编写
3.1 创建scrapy爬虫项目
创建项目,名为ProSearch,使用命令:
scrapy startproject ProSearch http://fz.people.com.cn
3.2 明确抓取字段
创建爬虫项目后,编写items.py文件,明确待抓取的字段
# -*- coding: utf-8 -*-
import scrapy
class ProsearchItem(scrapy.Item): # 关键词
keyword = scrapy.Field()
# 项目编号
pronums = scrapy.Field()
# 项目类别
protype = scrapy.Field()
# 学科类别
subtype = scrapy.Field()
# 项目名称
proname = scrapy.Field()
# 立项时间
protime = scrapy.Field()
# 负责人
leaders = scrapy.Field()
# 工作单位
workloc = scrapy.Field()
# 单位类别
orgtype = scrapy.Field()
# 所在省市
provloc = scrapy.Field()
# 所属系统
systloc = scrapy.Field()
3.3 生成爬虫文件
在cmd窗口进入到ProSearch项目后,生成爬虫文件。使用命令:
scrapy genspider SearchPro
3.4 编写爬虫逻辑
生成爬虫文件后,来到spiders文件夹下的SearchPro.py文件,开始辨写爬虫逻辑。
# -*- coding: utf-8 -*-
import scrapy
from ProSearch.items import ProsearchItem class SearchproSpider(scrapy.Spider): name = 'SearchPro' # 爬虫名称
allowed_domains = ['fz.people.com.cn']
# start_urls = ['http://fz.people.com.cn/skygb/sk/index.php/Index/seach']
page = 1 # 指定检索关键词
keywords = ['可持续', '互联网', '大数据', '能源']
# 角标
index = 0
# 年份
years = 2018 # POST提交参数
formdata = {
'xmname': '',
'xktype': '',
'xmtype': '',
'cglevel': '',
'cbdate ': '',
'cgxs': '',
'lxtime': '',
'ssxt': '',
'zyzw': '',
'dwtype': '',
'jxdata': '',
'szdq': '',
'pznum': '',
'cgname': '',
'jxnum': '',
'cbs': '',
'xmleader': '',
'hj': '',
'gzdw': '',
'zz': ''
} # 参数提交的url
url = "http://fz.people.com.cn/skygb/sk/index.php/Index/seach" def start_requests(self):
"""
POST请求实现一般是重写start_requests函数,指定第一个关键词为默认检索关键词
:return:
"""
self.formdata['xmname'] = '可持续'
self.formdata['lxtime'] = str(self.years)
yield scrapy.FormRequest(
url=self.url,
formdata=self.formdata,
callback=self.parse,
meta={'formdata': self.formdata}
) def parse(self, response):
"""
解析数据
:param response:
:return:
"""
if response.meta['formdata']:
formdata = response.meta['formdata'] # 每行数据所在节点
try:
node_list = response.xpath("//div[@class='jc_a']/table/*")[1:]
except:
print("关键词‘{}’无搜索结果!".format(formdata['xmname']))
for node in node_list:
# 提取数据
item = ProsearchItem()
# 关键词
item['keyword'] = formdata['xmname']
# 项目编号
item['pronums'] = node.xpath('./td[1]/span/text()').extract_first()
# 项目类别
item['protype'] = node.xpath('./td[2]/span/text()').extract_first()
# 学科类别
item['subtype'] = node.xpath('./td[3]/span/text()').extract_first()
# 项目名称
item['proname'] = node.xpath('./td[4]/span/text()').extract_first()
# 立项时间
item['protime'] = node.xpath('./td[5]/span/text()').extract_first()
# 负责人
item['leaders'] = node.xpath('./td[6]/span/text()').extract_first()
# 工作单位
item['workloc'] = node.xpath('./td[8]/span/text()').extract_first()
# 单位类别
item['orgtype'] = node.xpath('./td[9]/span/text()').extract_first()
# 所属省市
item['provloc'] = node.xpath('./td[10]/span/text()').extract_first()
# 所属系统
item['systloc'] = node.xpath('./td[11]/span/text()').extract_first()
yield item # 匹配下一页的数据
if '下一页' in response.xpath("//div[@class='page clear']/a").extract():
self.page += 1
n_url = self.url + '?' + 'xmname={}&p={}'.format(formdata['xmname'], self.page)
yield scrapy.Request(url=n_url, callback=self.parse, meta={'formdata': formdata}) # 匹配其他年份的数据
searcy_year = int(formdata['lxtime'])
if not searcy_year <= 2014:
searcy_year -= 1
formdata['lxtime'] = str(searcy_year)
print("检索关键词:{}!".format(formdata['xmname']))
yield scrapy.FormRequest(
url=self.url,
formdata=formdata,
callback=self.parse,
meta={'formdata': formdata}
)
# 其他关键词搜索
else:
self.index += 1
if not self.index > len(self.keywords)-1:
keyword = self.keywords[self.index]
print("更新检索关键词为:{}".format(keyword)) formdata['xmname'] = keyword
formdata['lxtime'] = str(self.years) yield scrapy.FormRequest(
url=self.url,
formdata=formdata,
callback=self.parse,
meta={'formdata': formdata}
)
3.5 编写数据保存逻辑
本项目用excel对数据进行保存。在pipelines.py文件中编写数据保存的逻辑。
# -*- coding: utf-8 -*-
from openpyxl import Workbook class ProsearchPipeline(object): def __init__(self):
# 创建excel表格保存数据
self.workbook = Workbook()
self.booksheet = self.workbook.active
self.booksheet.append(['关键词', '项目编号', '项目类别', '学科类别', '项目名称', '立项时间', '负责人', '工作单位', '单位类别', '所在省市', '所属系统']) def process_item(self, item, spider): DATA = [
item['keyword'], item['pronums'], item['protype'], item['subtype'], item['proname'], item['protime'], item['leaders'], item['workloc'], item['orgtype'], item['provloc'], item['systloc']
] self.booksheet.append(DATA)
self.workbook.save('./data/ProSearch.xls')
return item
3.6 其他细节
到此基本内容完成,设置一下settings.py文件对细节进行处理基本爬虫就可以运行了。
处理一:打开pipline通道
处理二:添加随机请求头并打开下载中间件
处理三:添加重拾、延时、log级别等
处理四:编写脚本main.py文件
scrapy默认使用命令行进行创建、生成、爬去等任务,可尝试在整个项目下编写一个main.py文件,将爬去命令添加到py文件中,直接在编辑器中F5运行。
下次每次运行main.py文件就可以直接运行了。
4.完整代码
scrapy抓取国家社科基金项目数据库的更多相关文章
- 通过Scrapy抓取QQ空间
毕业设计题目就是用Scrapy抓取QQ空间的数据,最近毕业设计弄完了,来总结以下: 首先是模拟登录的问题: 由于Tencent对模拟登录比较讨厌,各个防备,而本人能力有限,所以做的最简单的,手动登录后 ...
- python scrapy 抓取脚本之家文章(scrapy 入门使用简介)
老早之前就听说过python的scrapy.这是一个分布式爬虫的框架,可以让你轻松写出高性能的分布式异步爬虫.使用框架的最大好处当然就是不同重复造轮子了,因为有很多东西框架当中都有了,直接拿过来使用就 ...
- scrapy抓取淘宝女郎
scrapy抓取淘宝女郎 准备工作 首先在淘宝女郎的首页这里查看,当然想要爬取更多的话,当然这里要查看翻页的url,不过这操蛋的地方就是这里的翻页是使用javascript加载的,这个就有点尴尬了,找 ...
- scrapy抓取拉勾网职位信息(一)——scrapy初识及lagou爬虫项目建立
本次以scrapy抓取拉勾网职位信息作为scrapy学习的一个实战演练 python版本:3.7.1 框架:scrapy(pip直接安装可能会报错,如果是vc++环境不满足,建议直接安装一个visua ...
- scrapy抓取的中文结果乱码解决办法
使用scrapy抓取的结果,中文默认是Unicode,无法显示中文. 中文默认是Unicode,如: \u5317\u4eac\u5927\u5b66 在setting文件中设置: FEED_EXPO ...
- 分布式爬虫:使用Scrapy抓取数据
分布式爬虫:使用Scrapy抓取数据 Scrapy是Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘. ...
- 解决Scrapy抓取中文网页保存为json文件时中文不显示而是显示unicode的问题
注意:此方法跟之前保存成json文件的写法有少许不同之处,注意区分 情境再现: 使用scrapy抓取中文网页,得到的数据类型是unicode,在控制台输出的话也是显示unicode,如下所示 {'au ...
- scrapy抓取中国新闻网新闻
目标说明 利用scrapy抓取中新网新闻,关于自然灾害滑坡的全部国内新闻:要求主题为滑坡类新闻,包含灾害造成的经济损失等相关内容,并结合textrank算法,得到每篇新闻的关键词,便于后续文本挖掘分析 ...
- scrapy抓取斗鱼APP主播信息
如何进行APP抓包 首先确保手机和电脑连接的是同一个局域网(通过路由器转发的网络,校园网好像还有些问题). 1.安装抓包工具Fiddler,并进行配置 Tools>>options> ...
随机推荐
- unityevent与持续按键触发
上一篇中提到一种鼠标按下时的事件触发,即采用eventtrigger设定pointerdown和pointerup并绑定相应事件.但是若要实现持续按键则需要对绑定的每个方法都添加实现持续按键方法.所以 ...
- python中的可变数据类型和不可变数据类型
1.不可变数据类型:数值.字符串.元组 不允许变量的值发生变化,如果变量的值变化了,那么就是新建了一个对象:对于相同值的对象,在内存中只有一个对象. 2.可变数据类型:列表.字典 允许变量的值发生变化 ...
- django-模板之extends(三)
/book/base.html <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- 修改vuex状态机中的数据
vuex状态机中的数据是必须提交mutation来修改,如果现实开发中,我们需要修改,而又不想提交mutaition,应该怎么做呢? 先来回顾一下场景,有一个列表是存在vuex中的 这个列表展 ...
- plsql + instantclient 连接oracle ( 超简单)
1.instantclient 下载并解压 instantclient 下载地址 https://www.oracle.com/technetwork/cn/database/features/ins ...
- Java抽象类、接口、内部类
抽象类的概念: 1.Java中可以定义没有方法体的方法,还方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类: 2.如,shape类计算周长和面积的方法无法确定,那么就可以将这样 ...
- 爬虫之CrawlSpider简单案例之读书网
项目名py文件下 class DsSpider(CrawlSpider): name = 'ds' allowed_domains = ['dushu.com'] start_urls = ['htt ...
- 「2019.8.11 考试」一套把OI写的很诗意的题
这次写的更惨了,T2暴力再次挂掉了. 先写了T1的75暴力,然后写了T2的70分暴力(挂成了25),T3啥也不会骗了12分.T3看完题一点思路没有,心态爆炸了,一直在观察数据,忽略的思考的重要性,以至 ...
- 【工利其器】Android Lint篇——为Android量身定做的静态代码审查工具
前言 我们在进行代码优化的时候,往往是通过开发者的经验来判断哪些代码可能存在潜在问题,哪些资源的使用不合规范等.实际上Android SDK提供了一款功能非常强大的工具,来帮助开发者自动检测代码的质量 ...
- synchronized和ReentrantLock锁住了谁?
一.synchronized 案例1: public class LockDemo{ public static void main(String[] args) throws Exception { ...