用Python爬取金融市场数据

一、写在前面

由于在平时的工作中,需要对某信托网的信托在售和资管在售数据进行统计分析,但是一条一条的输入,显然太过耗时耗力,于是萌生了写个爬虫的想法。

一门计算机语言,可以当做是在模仿人的目的或意图来进行一系列行为或动作,所以在写代码之前,首先要弄清楚你要干什么,如果是你,你每一步的动作是什么,然后将这一步步的动作通过代码传递给计算机,让计算机高效的帮你完成即可。

本文结合正则表达式和比较流行的beautifulsoup(bs4),对网页进行解析并提取数据,因此在正式进行之前,有必要简单介绍下正则表达式和bs4.

二、基础知识

1、正则表达式

具体的详细介绍可自行去网上补知识,这里只介绍一些规则和常用的用法。

 

2、bs4

同样,详细知识自行补,这里只介绍常用的用法:select结合选择器的用法。

 

主要有以下几种提取规则:

 

三、开始实战——爬取某信托网的信托在售数据

1、爬取前的准备工作——梳理好代码的逻辑

正如前面所说,写代码之前,首先要清楚你想要干什么,如果是你,你是什么样的动作来达到你的这个目的或意图。

第一,你的目的或意图是什么,对于本例而言,我需要获取任意某页至某页信托在售产品的下面数据:产品名称、发行机构、发行时间、最高收益、产品期限、投资行业、发行地、收益分配方式、发行规模、最低收益、最高收益和利率等级划分情况这12个数据。

第二,如果是人,需要哪些动作来达到这个目的。我们来看下网页。动作就清晰了:

输入网址/搜索关键字 > 进入网站 > 点击红色框框里的信托产品和在售 > 录入下面绿色框框里的相关信息 > 发现信息不全,再点击这个产品,在详情页(再下一张图)继续录入。

b95a591cd683ea62c5ceea66896f0acb.jpg-wh_651x-s_3635574352

c89d5570e925c414e37dc439aa69c93f

2、开始爬取

既然动作清晰了,那就可以让计算机来模拟人的这个动作进行爬取了。

然后就是写代码的逻辑了。我们用做数学题常用的倒推法来梳理这个过程。

要想获取数据 < 你得解析网页给你的响应 < 你得有个响应 < 你得发送请求 < 你得有个请求request < 你得有个url。

然后我们再正过来解题:获取url > 构建request > 发送请求 > 获取响应 > 解析响应 > 获取所需数据 > 保存数据。

所以按照这个步骤,我们可以先做出一个大框架,然后在框架的基础上补充血肉。大框架,就是定义个主函数。

值得注意的是,本例中,每个产品的信息获取,我们都有二次点击的动作,即第一页数据不全,我们再点击进入详情页进行剩余数据的获取,因此,本例是有两层的数据获取过程的。第一层使用正则表达式,第二层使用bs4。

① 定义主函数

如下是这个主函数,前面的写入相关数据你可以先不管,这都是在第一步的获取url时,后补过来的。

回到前面的目的:提取任意某页至任意某页的数据,所以写个循环是必须的,然后在循环下方,两层网页的数据获取框架就出来了。(由于第二层网页的url是根据第一层网页的某个数据拼接出来的,而第一层网页是一下子提取整个页面所有产品的信息,所以第二层网页的提取也设置了个循环,对第一层网页的所有产品,一个一个点进去进行提取)

 

② 获取url —— 第一层和第二层通用

由于我们需要访问两层的数据,所以希望定义一个函数,能对两层的URL都可以进行拼接。

如下图为第一层页面的内容和源码,由第二个红框中的内容(X-Requested-With:XMLHttpRequest),可知这是一个AJAX get请求,且携带者第三个红框中的数据,而第三个红框中的数据,又恰好是第一个红框中的url的一部分,即为:

http://www.某信托网.com/Action/ProductAJAX.ashx?加上第三个红框中的数据。

第三个框框中包括几个可变的数据:pageSize(表示一页显示多少产品);pageIndex(表示第几页);conditionStr(定义产品类型,1表示信托,2表示资管),其余的数据都是固定的(这其中有个_:1544925791285这种下划线带一串数字的东西,像是个随机数,去掉也没影响,我就给去掉了)。

0cf9bdda9a69bd27884ba7e8382169b5

下图为第二层页面的内容和源码,可见只是一个简单的get请求,且网址很简单,就是一个http://www.某信托网.com/Product/Detail.aspx?加上一个id,而这个id又来自哪里呢,答案就在第一层网页的响应数据中(见再下面一幅图的红色框)。

bff76a0c9300aca33e1f35406104de44

752556dc93328a47d50f7eaf643f014e

通过上面的分析,第一层网页的请求url由一个固定的部分加上一些数据,第二层网页的url依赖于第一层的数据,我们先在主函数中将url_1、url_2和一些可变的数据写入(见上面的主函数),然后定义一个函数用来拼接两层的url即可,因为第一层网页url的固定部分长度为47,第二层的为43,这里使用一个长度条件来判断是拼接第一层还是拼接第二层。

 

③ 构建request + 获取response一条龙 —— 第一层和第二层通用

获取url后,接下来就是构建request用来发送请求获取响应了,此处定义一个函数实现一条龙服务。

这里为了提防反爬,user_agent在多个里随机选,并使用了代理池(虽然不多),并且我电脑端也进行了局域网ip代理。

 

④ 解析第一层网页的内容

获取响应之后就是解析并提取数据了,第一层使用正则表达式的方法来进行。

获取的response如下如:

7a349f81b3410ed4dd9cbdd36f6968d2

因此可写出如下正则,从左到右分配匹配出ID、产品名称、发行机构、发行时间、产品期限、投资行业、首页收益。

 

⑤ 解析第二层网页的内容并输出数据

第二层使用bs4中的select+选择器的方法来进行。除了第一层所提取的数据外,还需要发行地、收益分配方式、发行规模、最低收益、最高收益和利率等级分布情况。

网页如下,可见,我们所需要的信息隐藏在一个又一个tr标签里,而这个tr标签处于id=“procon1”下的一个table标签里(此处有个坑,就是从网页来看,table下还有个tbody标签,而实际得到的响应里并没有)。

13d19d60ddfd9cd6388adde530d15d52

由于我们不是所有的信息都要,所以我们可以一个一个的提取,最终输出个数据。代码如下(这中间用到了前面提到的选择器知识和一些字符串处理方法):

 

⑥ 保存数据到本地(以dataframe格式保存到本地CSV格式)

 

3、爬取结果

运行代码,这里以每页显示4个产品,爬取前3页的信托在售为例,运行结果如下:

1a32f66fda0806765bbd9c9ea527200c

然后打开存到本地的CSV文件如下:结果是美好的。

e932ea880471fb1d89a011acf5a967b5

这种两层网页的数据抓取,可以用在非常非常非常多的地方呦。

承接各种网站开发与修改、爬虫、数据采集分析、小程序等任务

Html+Css+JS+PHP+Nodejs+Python

专治网站各种不服

一起探讨,互相学习,共同进步!有事儿您说话。

This entry was posted in Python and tagged , by 织梦先生. Bookmark the permalink.