php抓取网页数据插入数据库(Wind(万德)金融终端是如何实现的?(一))
优采云 发布时间: 2021-12-03 16:15php抓取网页数据插入数据库(Wind(万德)金融终端是如何实现的?(一))
1.前言
Wind金融终端是我校学生常用的一款商业软件,提供了大量的金融实施数据,内容丰富,信息量大。Wind 几乎是我见过的付费商业软件中用户体验最好的之一。但是,正是因为其高昂的价格,才使得其保密性非常高,而且里面的数据也不容易得到。Wind官方为我们提供了api接口,但是这些接口还是不能满足我们更加个性化的数据需求。
同时,Wind是PC客户端程序,里面的数据没有浏览器方便。对于浏览器中的数据,可以使用大家非常熟悉的传统爬虫。但是,对于这种PC程序中的数据,还需要其他的方法来捕捉。
如果您需要按照本文所述进行实验,建议准备一个额外的外部屏幕。
2.问题描述
我们这里的目标是抓取风端的研究报告数据。Wind账号是极其昂贵的,这里我们不得不想象我们真的有一个Wind账号。
我们的目标主要是抓取每份研究报告中的一些具体数据,比如研究报告的作者、发布时间、180天内的评价次数和EPS值(见下图中红框),以及将其写入 csv 文件。
3.分析页面
众所周知,浏览器中的数据是以HTML的形式显示的。我们需要的数据可以通过爬虫轻松获取,辅以正则表达式、xpath等工具。事实上,许多Windows程序也有类似HTML页面的结构,但大多数Windows程序不提供检查功能。我们可以使用 Windows SDK 提供的检查器来检查程序中的元素。下图是一个例子,你可以在右图左边的树结构中看到风列表项的位置。
值得注意的是,Windows 程序的页面结构也可能足够复杂。经过我的计算,风之主页的页面节点总数近千。
一旦我们了解了Windows程序的页面结构,理论上肯定有办法批量获取页面上的数据。接下来的工作是找到合适的工具和枯燥的编程工作。
4.选择工具
这里我们选择uiautomation,一个Windows自动化测试工具。这个工具大家可能比较陌生,但是说到selenium,大家就都很熟悉了。Selenium 是用于 网站 测试的自动化测试工具。同时,像我这样的爬虫渣一般都是用selenium来爬取页面信息。自动化也是基于类似的原理,不仅限于web网站,它还可以自动化测试WindowsPC程序。Uiautomation 支持多种语言。在本文中,我们使用基于 python 的 uiautomation 框架。另外,你可以试试java等其他语言的uiautomation。
uiautomation 的python 版本的GitHub 链接在这里:
首先需要安装
pip install uiautomation
5.使用uiautomation选择窗口
接下来,我们需要选择窗口窗口进行后续操作。根据下图不难发现,窗口有一个唯一的类名,我们可以通过这个类名来选择。根据uiautomation作者的习惯,通常将uiautomation导入为auto,我们在下面的代码中也观察到了这个习惯。
import uiautomation as auto
wind = auto.WindowControl(searchDepth=1, ClassName="TMasterForm")
这里的 searchDepth 参数表示搜索深度。整个Windows界面以桌面为根节点,即深度为0,桌面中所有窗口的深度为1。
>>> wind.Name
'Wind金融终端..Everest'
这时候就可以显示窗口名称了,说明我们已经成功定位到该窗口了。
6.获取研究报告列表
当我们在检查器中选择一个列表项时,我们可以发现这些列表项的父元素是一个DataItemControl。对于wind之类的软件,大部分元素都是自定义元素,即CustomControl。Windows 没有提供很多元素,因此您可以通过 DataItemControl 找到它。
首先我们来获取研究报告平台这个子窗口中的内容,如下图所示。
yanbaoWindow = wind.WindowControl(ClassName='TfrmMyIEPageContainer')
接下来,我们可以通过在该子窗口中查找DataItemControl 来找到列表项的父元素。
table = yanbaoWindow.DataItemControl(foundIndex=3)
经过统计,需要的元素是研究报告平台窗口中的第三个DataItemControl,所以指定参数foundIndex = 3。一般来说,PC程序中每个页面的结构都比较稳定,所以可以指定为前三个来查找。
接下来,根据检查器显示的结构关系,我们可以获取并打印这些研究报告的名称:
lines = table.GetChildren()
for line in lines:
c = line.GetChildren()[0]
name = c.GetChildren()[2]
analyst = c.GetChildren()[3]
print(name.Name, analyst.Name)
名称与页面上的研究报告名称相对应。
接下来,我们需要获取研究报告详情页中的信息。这时候就应该模拟一下鼠标的点击操作了。方法也很简单。
name.Click()
就是这样。值得注意的是,uiautomation中的方法命名几乎采用了类似C#的风格,所有的方法名都是用大驼峰命名的,很奇怪。执行 Click 方法后,您将进入详细信息页面。
需要注意的是,由于uiautomation与selenium驱动不同,通过browserdriver控制浏览器进行操作,即uiautomation是没有appdriver的,所以在进行模拟操作的时候一定要保证被点击的对象是在屏幕上方可见范围内,根据位置进行操作,否则会抛出异常。这时候鼠标会被控制,真正点击目标,用户尽量不要使用鼠标。
7.退出详情页
进入详情页后,我们可以用类似的方法抓取我们需要的所有数据。我不会在这里详述。抓取后,我们应该关闭详细信息页面并返回列表页面。我们注意到可以使用快捷键Ctrl+W,所以可以模拟使用快捷键关闭详情页。
auto,SendKeys("{Ctrl}w")
8.效果图
渲染中的操作都是由程序控制的。
9.总结
综上所述,在本次实战中,我们发现了传统爬虫与Windows程序的一些共同点。HTML 页面和 Windows 程序都具有类似的树状页面结构,因此可以通过某种方式获取元素。相比之下,Windows 程序更复杂,提供的工具更少,因此难度更大。