Advertisement

python把excel填充到网页_Python获取某网页数据并写入excel

阅读量:

请各位原谅, 特别是涉及消费金融及财务工作的同事, 请问您有什么事务我正在跟进中吗?很快就会完成。

bd22817aaa44ed5816c6654f974b58bd.png

在年前假期刚开始时,一位名叫征征的同业人员Approach'd the author, pointing at a display of a certain票据交易所 interface and asking, '能否将这些数据复制下来?'

c7694dfb71b6aa8b47b4acad0d1ddc3f.png

笔者仔细观察了一下这个破旧的界面后,内心嘀咕着:这个功能确实无法直接选中并复制后粘贴到Excel里就可以了。不过毕竟是部门内部提出来的意见和建议嘛,事情没那么简单。于是征征提出了一个严肃的问题:

7e71a2966bfc8c4cbcd72c398061b261.png

该网页不具备批量导出功能;即若要查询一个月内的利率或收益率情况,则必须逐一点击日期并随后将数据复制粘贴至表格中。已经过去了大约一半的时间;这样的设计确实让人觉得非常低效;忍无可忍实属遗憾!

于是笔者对这个网站进行了深入研究,并计划开发一个高效的爬虫系统来协助同业部减少人力投入。为了避免将宝贵的精力投入到低效工作中。

8c9433212b9a9ee778218a16708056bc.png

所谓爬虫本质上讲就是哲学的核心问题:我们是谁?我们从哪里来?我们要前往哪里?

8862d92394c1350b34d24ffaf48cab87.png

首先了解数据结构:通过图表可以看出,在这种情况下,
看起来比较简单,
日期与期限各自对应着各自的利率和收益率。
此外,在非工作day没有相应的data.

46529569081273a2ad0c327738ae99dc.png

再看数据如何获取?

这个网页是个明显的动态网页,而且有反爬虫机制,使用最简单的urllib库直接就被503拒绝掉,此时有两种方案:方案A,使用selenium库,模拟点击日期,然后复制数据,最后导出。但是这个方法有很大的缺陷,首先是要在电脑上安装高版本的谷歌浏览器(这个不难)和对应的webdriver(这个就有点麻烦了),其次点击时会调用一个谷歌浏览器进程,众所周知谷歌浏览器进程是出了名的吃内存,一旦浏览器卡住(同业的老爷机是必然会被卡住的)就前功尽弃,最重要的是这种模拟点击的方式为了绕过反爬虫机制每次操作不能太快,所以效率低下。

69e29cb219eae2853eec7263b9fd9e89.png

仅限于方案B:依靠requests和fake_useragent库生成模拟的正常用户请求以获取数据

说起来简单,干起来也不复杂,只需要导入两个库即可:

32f11c8b41074bfc1b3a3479a1ff094c.png

然后使用fake_useragent伪造一个正常的head:

ec8d4e62119e45bbdbd7c54984f5dd25.png

然后重点来了,开始分析这个网页,看是如何进行交互的:

启动谷歌浏览器。
切换至开发者工具。
重新刷新页面。
随意选择几个日期。
在XHR中细致查看。
发现了问题所在:虽然这是一个动态网页(推测是否采用了Ajax技术),但实际上是通过POST请求发送了数据,并由服务器返回了一个JSON格式的数据。

024601739962940e451e6fb34be18859.png

返回的值如下:

0f4c86ece5322905c16edee72162fc97.png

这正是我们需要的。

OK, 需求分析已顺利完成, 正式进入代码编写阶段。首先需要确定项目起始时间和结束时间点, 并采取措施防止接收到无效的请求。具体实施步骤为以下几点:

用户指定起始时间和截止时间后,在系统内自动生成每一天的具体信息,并将其存储在一个列表中。接着从该列表依次提取日期数据,并将其整合进伪造的POST请求结构中。

听起来很简单啊!但实际操作起来却并不轻松。核心问题在于Python的数据类型转换过程极其复杂啊!(PHP 万岁)

首先是对起始时间和结束时间进行获取操作。接着生成每一个单独的日子,并将这些日期逐个加入循环体中(这样做的原因在于Python代码通常显得简洁明了;然而实际上使用起来却较为繁琐;如果进行嵌套处理则会非常棘手;因此选择直接展开循环结构)

7e5e7d70fee03f5535dc8a5b6d94bf04.png

然后使用datetime判断是否为工作日,如果是工作日,就继续:

531a0622c51ddb7c3f7cb7fbb36a6aa3.png

由于用户的输入格式为yyyymmdd,在post请求中需要使用yyyy-mm-dd的格式进行处理。因此必须执行格式转换操作。具体步骤如下:将原始数据转换为字符串类型,并分别提取年份的前两位、月份的两位以及日期的后两位数字信息;最后将这些提取到的数据部分用横杠符号将其分隔开来形成最终的目标数据结构。

8d0811160b9c9531d42bab948f7eb5d4.png

将拼接完成后的日期录入到payload中,并配合模拟生成的head数据向服务器发起请求

6fab421d06a17b8697f806679650ef36.png

随后利用 Beautiful Soup 和 lxml 进行数据整理,并再利用看似繁复且书写的繁重但熟悉后变得简便的正则表达式进行数据处理

f516fea638f2c87f366dc315a5baa8ef.png

为了防止太过分,所以加点间隔时间,避免引起对方的警觉:

0ee15c5a61e6af5b11690efcca9f8513.png

最后把获取的数据存到dataframe,写入到excel中,搞定!

454cc9b210fc7131296048d4e33a80ef.png
ad085bbd6b4123454cff12d6e3d38040.png

最后,一个爬虫写了70多行也是醉了。

全部评论 (0)

还没有任何评论哟~