近年来,大数据盛行,有关爬虫的教程层次不穷。那么,爬虫到底是什么呢?

什么是爬虫?

百度百科是这样定义的:

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫更多解释

就我个人理解,所谓的爬虫,就是代替人工复制粘贴去获取网络资源。平常我们需要批量下载图片、下载表格数据时,在没有爬虫的帮助下,只能借助CTRL+C 、CTRL+V 了,非常的繁琐,还容易出错。但是,你会发现,这些资源呈现出来,都是经过整理的。图片的链接是有规律的字符串,数据的网页源码是有规律的标签包住的(比如用的是同一个Class,同一种标签。)。这些都是可以程序化的东西。我们通过编程,将这些有规律的东西,用正则表达式来表达出来,然后交给代码去提取内容,这样就是爬虫爬取数据的具体表现了。

MATLAB爬取股票数据

相信大家听的比较多的应该是用 Python 来爬取网页数据了,但其实,Matlab 也是可以的,这里我们来具体实现一下。场景是这样的:

链接:http://vip.stock.finance.sina.com.cn/corp/go.php/vMS_MarketHistory/stockid/000001/type/S.phtml?year=2017&jidu=4

新浪财经提供了历年各个季度的各股票数据,今天我们的任务就是,将上证综合指数(000001)1991年到1992年的数据爬取到,然后整理出来,保存到两个excel中,每个excel包括当年四个季度的数据,数据如上图所示,包括日期,开盘价、最高价、收盘价、最低价、交易量、交易金额。

爬取流程

本次爬取股票数据的流程是这样的:

观察网址规律

首先,观察当选择不同的年份与季度时,网页链接是有规律的:

http://vip.stock.finance.sina.com.cn/corp/go.php/vMS_MarketHistory/stockid/000001/type/S.phtml?year=2017&jidu=4
  • stockid/000001 指明了所选股票代码
  • year=2017 指明了所选的年份
  • jidu=4 指明了所选季度

那么,通过观察,我们就可以知道,当修改对应的数字,就可以获取到不同年份和季度下的数据网页了。在代码里设置两层循环就可以搞定了。

提取网页内容

确定网址后,我们可以利用函数获取到当前网址的源码,什么是源码?在网页里右键,查看源码你就知道了,长这样:

在Matlab里,提供了urlread函数来获取源码,语法参考如下:

str = urlread(URL)
str = urlread(URL,Name,Value)
[str,status] = urlread(___)
  • str = urlread(URL) 将 HTML 网页内容从指定的 URL 下载到字符向量 str 中。urlread 不检索超链接目标和图像。
  • str = urlread(URL,Name,Value) 使用一个或多个 Name,Value 对组参数指定的其他选项。
  • [str,status] = urlread(___) 禁止显示错误消息,并使用先前语法中的任何输入参数。当操作成功时,status 为 1。否则,status 为 0

也就是说,我们利用urlread函数会得到源码的文本。就像上图所示的那样,全是字符串。

观察提取内容的规律

我们提取的是股票的日期,开盘价、最高价、收盘价、最低价、交易量、交易金额。并且这些内容全部在源码里面了。源码是一堆乱七八糟的html标签还有Js等等。如何提取出我们想要的东西呢?这需要我们去观察源码。

匹配日期

首先定位到表格,通过F12,查看源码后,点击左下角的箭头,将箭头放到表格附近,就可以定位到元素的源码位置了。

其中日期的附近的源码是这样的:

<div align="center">
<a target="_blank" href="http://vip.stock.finance.sina.com.cn/quotes_service/view/vMS_tradehistory.php?symbol=sh000001&amp;date=2017-12-28">
2017-12-28 </a>
</div>

仔细观察,在 2017-12-28 的前后都存在大量的空格,通过正则表达式,我们可以将其表述出来:

\s+(\d\d\d\d-\d\d-\d\d)\s*

怎么理解?\s+ 表示可以出现空格、换行、制表符等一次或者多次,(\d\d\d\d-\d\d-\d\d) 表示所有满足形如 2017-12-28这样的数字组合,\d代表0~9的阿拉伯数字,括号则表示所有满足这一组表达式匹配到的字符集合。最后\s*则表示末尾可以出现空格、换行、制表符等零次或者多次。通过正则表达式,可以提取到当前源码里所有满足这个规律的日期,从而返回相应的数据,这里使用matlab自带的regexp函数,具体语法如下:

startIndex = regexp(str,expression)
[startIndex,endIndex] = regexp(str,expression)
out = regexp(str,expression,outkey)
[out1,...,outN] = regexp(str,expression,outkey1,...,outkeyN)
___ = regexp(___,option1,...,optionM)
___ = regexp(___,'forceCellOutput')
  • startIndex = regexp(str,expression) 返回 str 中与该正则表达式指定的字符模式匹配的每个子字符串的起始索引。如果没有匹配项,则 startIndex 为空数组。
  • [startIndex,endIndex] = regexp(str,expression) 返回所有匹配项的开始和结束索引。
  • out = regexp(str,expression,outkey) 返回 outkey 指定的输出。例如,如果 outkey 为 'match',则 regexp 返回与该表达式匹配的子字符串而非其开始索引。
  • [out1,...,outN] = regexp(str,expression,outkey1,...,outkeyN) 按指定的顺序返回多个输出关键字指定的输出。例如,如果您指定 'match'、'tokens',则 regexp 返回与整个表达式匹配的子字符串以及与部分表达式匹配的标文。
  • ___ = regexp(___,option1,...,optionM) 使用指定的选项标志修改搜索。例如,指定 'ignorecase' 以执行不区分大小写的匹配。您可以包括任何输入并请求之前语法中的任何输出。
  • ___ = regexp(___,'forceCellOutput') 以标量元胞的形式返回每个输出参数。元胞包含被描述为上述语法输出的数值数组或子字符串。您可以包括任何输入并请求之前语法中的任何输出。

匹配数据

同理,我们也可以观察剩下的数据源码:

<td><div align="center">3295.246</div></td>

观察可以发现,数据都被<div align="center">xxx</div>所包住,所以正则表达式为:

<div align="center">(\d*\.?\d*)</div>

即被标签包住,且数据满足整数或者小数。

数据整理与导出

通过上面的正则表达提取字符串后,进行一些数据的整理,例如,字符串转数字,行列重排等等,然后将其写入到excel中。这里的步骤就不细说了。

完整源码

最后贴出源码(源码是在CSDN找到的,原链接:https://blog.csdn.net/miscclp/article/details/26839095)

% 本程序用于获取网站中的表格

% written by longwen36
% all rights reserved clc,clear; warning off; for year = 1991:1992 %年份
for jidu = 1:4 fprintf('%d年%d季度的数据...', year, jidu)
[sourcefile, status] = urlread(sprintf('http://vip.stock.finance.sina.com.cn/corp/go.php/vMS_MarketHistory/stockid/000001/type/S.phtml?year=%d&jidu=%d', year,jidu)); if ~status
error('读取出错!\n')
end expr1 = '\s+(\d\d\d\d-\d\d-\d\d)\s*'; %获取日期
[datefile, date_tokens]= regexp(sourcefile, expr1, 'match', 'tokens'); date = cell(size(date_tokens)); for idx = 1:length(date_tokens)
date{idx} = date_tokens{idx}{1};
end expr2 = '<div align="center">(\d*\.?\d*)</div>'; %获取数据 [datafile, data_tokens] = regexp(sourcefile, expr2, 'match', 'tokens'); data = zeros(size(data_tokens)); for idx = 1:length(data_tokens)
data(idx) = str2double(data_tokens{idx}{1});
end data = reshape(data, 6, length(data)/6 )'; %重排 filename = sprintf('%d年',year);
pathname = [pwd '\data']; if ~exist(pathname,'dir')
mkdir(pathname);
end fullfilepath = [pwd '\data\' filename];
% 保存数据到Excel
sheet = sprintf('第%d季度', jidu);
xlswrite(fullfilepath, date' , sheet);
range = sprintf('B1:%s%d',char(double('B')+size(data,2)-1), size(data,1));
xlswrite(fullfilepath, data, sheet, range);
fprintf('OK!\n') end
end fprintf('全部完成!\n')

运行结果展示

点击运行后,命令行窗口会提示当前状态:

每写入一个季度的数据,就会提示一次OK,直到全部完成。

同时,在当前运行的文件下,会多出一个data文件夹,里面包括了1991和1992两个excel,打开后表格里有四个季度的数据:

有关正则表达式

MATLAB爬虫爬取股票数据的更多相关文章

  1. 使用python爬虫爬取股票数据

    前言: 编写一个爬虫脚本,用于爬取东方财富网的上海股票代码,并通过爬取百度股票的单个股票数据,将所有上海股票数据爬取下来并保存到本地文件中 系统环境: 64位win10系统,64位python3.6, ...

  2. 用Python爬取股票数据,绘制K线和均线并用机器学习预测股价(来自我出的书)

    最近我出了一本书,<基于股票大数据分析的Python入门实战 视频教学版>,京东链接:https://item.jd.com/69241653952.html,在其中用股票范例讲述Pyth ...

  3. python网络爬虫(10)分布式爬虫爬取静态数据

    目的意义 爬虫应该能够快速高效的完成数据爬取和分析任务.使用多个进程协同完成一个任务,提高了数据爬取的效率. 以百度百科的一条为起点,抓取百度百科2000左右词条数据. 说明 参阅模仿了:https: ...

  4. python爬虫爬取天气数据并图形化显示

    前言 使用python进行网页数据的爬取现在已经很常见了,而对天气数据的爬取更是入门级的新手操作,很多人学习爬虫都从天气开始,本文便是介绍了从中国天气网爬取天气数据,能够实现输入想要查询的城市,返回该 ...

  5. python爬虫——爬取网页数据和解析数据

    1.网络爬虫的基本概念 网络爬虫(又称网络蜘蛛,机器人),就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序.只要浏览器能够做的事情,原则上,爬虫都能够做到. 2 ...

  6. 手把手教你用Node.js爬虫爬取网站数据

    个人网站 https://iiter.cn 程序员导航站 开业啦,欢迎各位观众姥爷赏脸参观,如有意见或建议希望能够不吝赐教! 开始之前请先确保自己安装了Node.js环境,还没有安装的的童鞋请自行百度 ...

  7. python爬虫----爬取阿里数据银行websocket接口

    业务需求:爬取阿里品牌数据银行的自定义模块==>>>人群透视==>>>查看报告==>>数据 发现:数据通过websocket接口传递,此类型接口的详细理 ...

  8. python爬取股票最新数据并用excel绘制树状图

    大家好,最近大A的白马股们简直 跌妈不认,作为重仓了抱团白马股基金的养鸡少年,每日那是一个以泪洗面啊. 不过从金融界最近一个交易日的大盘云图来看,其实很多中小股还是红色滴,绿的都是白马股们. 以下截图 ...

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

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

随机推荐

  1. 恕我直言,在座的各位根本不会写 Java!

    恕我直言,在座的各位根本不会写 Java! java思维导图 作者:Lrwin,软件架构师. 导语 自 2013 年毕业后,今年已经是我工作的第 4 个年头了,总在做 Java 相关的工作,终于有时间 ...

  2. solidworks 学习 (二)

    洗手液瓶建模

  3. nginx.conf 配置解析之 http配置

    官方文档 http://nginx.org/en/docs/参考链接: https://segmentfault.com/a/1190000012672431参考链接: https://segment ...

  4. 安装和启动ElasticSearch服务遇到的几个问题

    首先安装和启动服务的教程是参考文章:ES入门之一 安装ElasticSearch 然后在最后的启动es服务时遇到了几个小问题,因此在这里记录一下. 因为我对linux并不是很熟悉,因此文中如果有说错的 ...

  5. 【BigData】Java基础_循环

    1.for循环 语法: for (初始表达式;布尔表达式;步进) { 循环体: } 实例: package cn.test.logan.day02; import java.util.Scanner; ...

  6. fluent在运行时改变重力方向方法总结

    Fluent版本:19.0(其他版本应该也适用) 这里我们用一个简单的算例(同心环中的自然对流)来说明 算例来自<ANSYS Fluid Dynamics Verification Manual ...

  7. Android开发:文本控件详解——RadioButton和CheckBox(一)基本属性

    一.RadioButton和RadioGroup: RadioButton是单个的圆形单选框,而RadioGroup是可以容纳多个RadioButton存在的容器,因此RadioButton和Radi ...

  8. ubuntu之路——day18 用pytorch完成CNN

    本次作业:Andrew Ng的CNN的搭建卷积神经网络模型以及应用(1&2)作业目录参考这位博主的整理:https://blog.csdn.net/u013733326/article/det ...

  9. unity EditorGUILayer绘制报错

    最近在开发一个可视化工具的时候,遇到了一个代码错误,小小的记录一下 具体的报错信息:ArgumentException: Getting control 0's position in a group ...

  10. Json文件的BOM

    1.什么是BOM BOM: Byte Order Mark UTF-8 BOM又叫UTF-8 签名,其实UTF-8 的BOM对UFT-8没有作用,是为了支持UTF-16,UTF-32才加上的BOM,B ...