分享

Python大佬批量爬取中国院士信息,告诉你哪个地方人杰地灵

 太极混元天尊 2018-05-27



摘要

院士(Academician)源于Academy, Academy是古希腊传说中的一位拯救雅典免遭劫难而牺牲的英雄,属于科学及学术界的最高荣誉头衔。哪里盛产生院士?python爬虫告诉你。

背景调研

目前中国院士共有1500余人,其中科学院院士799人,工程院院士875人。

  • 科学院院士名单 

    http://www.casad.cas.cn/chnl/371/index.html

  • 工程院院士名单 

    http://www./cae/html/main/col48/column_48_1.html

这里我以工程院院士信息抓取进行讲解。

工程院士出生地分布图

必备模块

  • 通过 pip 安装scrapy 爬虫框架模块

  • 通过 pip 安装 jieba 分词模块

  • 通过 pip 安装win32api
    如果报ImportError: DLL load failed: 找不到指定的模块。 安装好后,把 D:\Python27_64\Lib\site-packages\pywin32_system32下的所有东西拷贝到C:\Windows\System32下面

爬虫流程

在E盘下面建立文件夹project_scrapy,

  • 建立爬虫项目 在E盘下面建立文件夹project_scrapy,进入该文件夹下面,打开cmd窗口,然后运行下面的命令搭建爬虫框架。 scrapy startproject engaca_spider 目录树如下:

E:\project_scrapy>tree /f
卷 新加卷 的文件夹 PATH 列表
卷序列号为 00000001 7009:36A5
E:.
└─engaca_spider
 │  scrapy.cfg
 │
 └─engaca_spider
     │  items.py
     │  middlewares.py
     │  pipelines.py
     │  settings.py
     │  __init__.py
     │
     └─spiders
             __init__.py
  • 设置输出内容 在items.py 中添加如下内容

# -*- coding: utf-8 -*-
import scrapy
class EngacaSpiderItem(scrapy.Item):
 # define the fields for your item here like:
 # name = scrapy.Field()
 name = scrapy.Field()
 place = scrapy.Field()
 pass
  • 在settings.py 中设置爬虫源头
    在settings.py 文件添加如下语句

starturl = 'http://www./cae/html/main/col48/column_48_1.html'
  • 省份列表文件 scrapy.cfg的同层文件夹中存放pro_list.txt

    链接:https://pan.baidu.com/s/1-fr_kWtIgzzjsNV_2Yu0JA 密码:vrsu

  • 爬虫核心代码 在spiders文件夹下面建立 aca_spider.py

#!python
#coding: utf-8
import scrapy
from scrapy.spiders import Spider
from scrapy.selector import Selector  
import re
from engaca_spider.settings import starturl
from engaca_spider.items import  EngacaSpiderItem
from pprint import pprint
import json
import urllib
from urlparse import urljoin  
import jieba
pro_list =[ i.strip().decode('utf-8')  for i in  open('pro_list.txt').readlines()]
class EngAcaSpider(Spider):
 '''
 '''

 name = 'EngAca'

 #需要处理的http状态
 handle_httpstatus_list = [404,403]

 def start_requests(self):
     '''
     '''

     yield scrapy.Request(starturl,self.getnames)

 def getnames(self,response):
     '''
     '''

     if response.status == 403:
         print 'meet 403, sleep 600 seconds'
         import time
         time.sleep(600)
         yield scrapy.Request(response.url, callback=self.getnames)
     #404,页面不存在,直接返回即可
     elif response.status == 404:
         print 'meet 404, return'
     #正常处理
     else:
         print 'second:',response.url
         self.logger.info('a response from %s',response.url)

         names_li=response.selector.xpath('//li[@class='name_list']/a')
         for name_li in names_li:
             '''
             '''

             items=EngacaSpiderItem()
             items['name']=name_li.xpath('./text()').extract_first()  #unicode
             urlhref=name_li.xpath('./@href').extract_first()
             newurl=urljoin(response.url,urlhref)
             yield scrapy.Request(newurl,callback=self.getplaces,meta={'items':items})

 def getplaces(self,response):
     '''
     '''

     items = response.meta['items']

     # get first content;
     #  中英文 混用 .encode('gbk','ignore')  忽略英文空格
     ptext=response.selector.xpath('//div[@class='intro']/p[1]/text()').extract_first()
     content=ptext.split(u'。')[1]        
     seg_list = jieba.cut(content)
     for place in seg_list:
         place=place.replace(u'省','')
         place=place.replace(u'市','')
         print 'place:',place
         if place in pro_list:
             items['place']=place
             break
     else:
         items['place']='None'
     pprint(items)
     yield items
  • 结果输出代码 在pipelines.py 处理输出内容,可以把内容保存到数据库或者文本中。 这里我直接保存到文本result.txt中。

# -*- coding: utf-8 -*-
class EngacaSpiderPipeline(object):
 def process_item(self, item, spider):
     return item
from pprint import pprint
import codecs
class ShopinfoPipeline(object):
 def process_item(self, item, spider):
     return item
class JsonWithEncodingPipeline(object):  
 def __init__(self):                    
     self.file = codecs.open('result.txt', 'w', encoding='utf-8')  #保存为json文件
     line='name  place\n'
     self.file.write(line)#写入文件中
 def process_item(self, item, spider):
     '''
     '''

     keylist=['name','place']
     baseline=''
     for i in keylist:
         baseline+=item[i]+' '
     baseline+='\n'
     pprint(baseline)
     self.file.write(baseline)#写入文件中
 def spider_closed(self, spider):#爬虫结束时关闭文件
     self.file.close()
  • 在settings.py指定输出管道

ITEM_PIPELINES = {
'engaca_spider.pipelines.JsonWithEncodingPipeline': 300,
}

运行爬虫

在这个目录scrapy.cfg的同层文件夹下打开cmd窗口运行爬虫,在该目录下生成结果文件result.txt。

scrapy crawl EngAca

利用pycharts进行数据可视化

参照教程,绘制地图热图。微信好友的全国分布的热图,你的微信朋友遍布全中国了吗?

从这张图上,我们可以看出江苏院士最多,超过100人,人杰地灵当之无愧。

项目所有文件

链接:https://pan.baidu.com/s/1-fr_kWtIgzzjsNV_2Yu0JA 密码:vrsu

总结

这是最基本也是最重要的爬虫练习。里面没有涉及到JS加密、反爬措施。借助这个练习,可以熟悉爬虫框架。 数据预测未来,做事先人一步。



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多