ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 16961|回复: 21

[分享] 解说一下,关于读取网页表格

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2014-8-8 16:27 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:网页交互
论坛上经常有朋友在网页表格数据抓取方面求取,呃...... 多集中于股票和彩票,这方面个人不是很感兴趣,不过仅从代码的角度,还是可以说说的
读取网页有数据流方式(XMLHTTP)和对象模式,各有利弊,这里拿网页对象模型说说,因为数据流的话,提析数据往往要用到正则解析之类的字串分析,初学的朋友眼都会花掉吧。

附件是完成的一个VBA,主程序SAMPLE,有两个例子,一个是本论坛VBA页面,另一个是在HAO123找的股票表格
附件的代码见后面,这里只说说原理,理解了灵活运用。

代码的主要部分是下面那个getTableByNumber函数,调用方式是
  1. CALL getTableByNumber(网页地址,网页上要抓取的表格编号,要把数据导出的RANGE对象)
复制代码
首先假设你已经对打开IE APPLICATION对象已经了解了,这部分不讲(以前发过相关OX),总之是创建InternetExplorer.Application,等它完全打开,最后关掉这个APPLICATION
我们从Set tableX = Ie.document.getElementsByTagName("table")(TableNumber) 这一行开始讨论

在网页的DOCUMENT模型中,TABLE是标准的网页元素,因此它可以用上一级网页元素的getElementsByTagName方法取得所有TABLE的集合
  1. Set 表格集合 = Ie.document.getElementsByTagName("table")(TableNumber)
复制代码
这里网页新手注意一下,取得的是集合而不是单张表,它是一个网页架构上的colletion集合,与我们EXCEL VBA的大部分集合差不多,
但这种集合的计数属性是length而不是count,从0开始使用下标,使用FOR N=X TO Y 循环计数时,就要用 FOR I=0 TO 表格集合对象.length-1 遍历,
当然用FOR EACH我就不管了.

表格集合对象的ITEM是每张表,要抓取指定表格,请在网页源文本里查出表的位置.
以ID定位是最好的,但我们不指望每个网页表都有ID,所以用表出现的次序定位,第一个<TABLE>是0号表格,第N个<TABLE>自然是N-1号表格
得到表集合以后,用
set 表格对象变量=表格集合(I)  得到具体的第I张表

然后是表格中单元格数据的定位.
在EXCEL里,RANGE对象有ROWS子集和COLS子集定位行列,或者用RANGE对象.CELLS(ROW,COL)定位第ROW行第COL列的单元格

TABLE也有行\列属性,行集合是TABLE对象.ROWS,列是COLS
同样具体定位I行就是
SET 行对象=表格对象.ROWS(I)
不再解说列对象,它的调用是相似的

行对象属于网页元素<TR>,它有CELLS集合访问"本行的每一个单元格"——注意与EXCEL的RANGE.CELLS(X,Y)不同,因为它只是“行”,所以只要给出列序号即可
行对象.CELLS(j)   '<==访问这行的第J个单元格

换一种说法,我们还可以用  表格对象.ROWS(i).CELLS(J)    访问这个网页表格的第I行第J个单元格

后面就不详细解释了,一句话就是当定位到具体单元格后,读取文本到EXCEL的RANGE

SAMPLE代码给出两个例子,都是定义了 URL网页位置\表格出现的编号 读取数据到第一个工作表,
不过股票的赋值已经注释掉,有兴趣自已试验

代码只是作为参考,读取网页的函数本身固定了把抓取的数据放到SHEET1,并不是说一定要用这种格式,各位朋友请在理解以后,灵活运用
  1. Option Explicit

  2. Sub sample()
  3. Dim myUrl As String, myTableNumber As Integer
  4. Dim shtX As Worksheet, rngX As Range
  5.   
  6.   '指定网页URL
  7.   
  8. 'myUrl = "http://www.hao123.com/stocknew"
  9. 'myTableNumber = 0  '<==第一张表是0号表,依次类推
  10.   
  11.   myUrl = "http://club.excelhome.net/forum-2-1.html"
  12.   'myTableNumber = 0  '<==第一张表是0号表,依次类推
  13.   
  14.   '指定网页上的表格编号,自已在网页源里测试
  15.   myTableNumber = 4  '<==第一张表是0号表,依次类推
  16.   
  17.   '设置要显示网页内容的目标位置,这里是在第一张表的A2
  18.   Set shtX = ThisWorkbook.Worksheets(1)
  19.   Set rngX = shtX.Range("a2")
  20.   
  21.   shtX.Cells.ClearContents
  22.   Call getTableByNumber(myUrl, myTableNumber, rngX)
  23. End Sub


  24. Sub getTableByNumber(Optional Url As String, Optional TableNumber As Integer, Optional rngX As Range)
  25.     Dim Ie

  26.    

  27.     Set Ie = CreateObject("InternetExplorer.Application")
  28.    
  29.     With Ie
  30.         .Visible = True  '<==自定,调试时可设为显示
  31.         .navigate Url
  32.         
  33.         Do Until .readyState = 4
  34.             DoEvents
  35.         Loop
  36.     End With
  37.    
  38.     Dim docX, tableX, row, tdGroup
  39.     Dim I, J
  40.    
  41.     Set tableX = Ie.document.getElementsByTagName("table")(TableNumber) '<==网页所有表格的集合
  42.    
  43.     '遍历此表的所有行,TD标签.
  44.     '在此说明一下TABLE相关属性,ROWS是行数,COLS是列数
  45.     '网页集合的计数是从0开始
  46.     For I = 0 To tableX.rows.Length - 1
  47.       
  48.       Set row = tableX.rows(I)
  49.       '遍历每行所有表格
  50.       For J = 0 To row.Cells.Length - 1
  51.          
  52.           '显示内容,注意在EXCEL里RANGE集合取表格位是从1开始,所以要加1
  53.           rngX.Cells(I + 1, J + 1) = row.Cells(J).innerText
  54.       Next
  55.     Next
  56.     Ie.Quit
  57. End Sub


复制代码

网页表格读取函数.rar

11.97 KB, 下载次数: 750

TA的精华主题

TA的得分主题

发表于 2014-8-8 16:54 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
你 应该用XMLHTTP+HTMLFILE两个对象来解决,比用IE打开效率上提高太多了

TA的精华主题

TA的得分主题

发表于 2014-8-8 17:04 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
wudixin96 发表于 2014-8-8 16:54
你 应该用XMLHTTP+HTMLFILE两个对象来解决,比用IE打开效率上提高太多了

二锅好,最近不露面...

TA的精华主题

TA的得分主题

发表于 2014-8-8 17:08 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 0wchz 于 2014-8-8 17:10 编辑

谢谢学习了Document.all.tags("td")那这是什么对象,如何加到你的代码里?

TA的精华主题

TA的得分主题

发表于 2014-8-8 17:16 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-8-8 17:19 | 显示全部楼层
一般我也用IE对象法来取网页数据,
因为XML用不大来。。  继续学习

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-8-8 18:31 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
wudixin96 发表于 2014-8-8 16:54
你 应该用XMLHTTP+HTMLFILE两个对象来解决,比用IE打开效率上提高太多了

主贴已经解释了为什么用网页对象模型作例子。

XMLHTTP数据流的好处是快捷,但没有经过WEB模型解析,在HTTP文本中要用正则(或相当于正则)的方法分析字符,
另一个问题是因为没有解析,在WEB OPEN之后能用HTTP接口分析出的WEB对象模型——比如说内嵌文件生成、代码生成的动态目标对象,在原始文本数据流中是看不到的。

网页对象的问题正好相反,解析过程是在解析引擎中完成,速度较慢。

对初学者来说,对网页层次对象的分析更直观更好理解。

点评

都说了用HTMLFILE对象,根本不需要什么正则  发表于 2014-8-8 22:26

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-8-8 23:10 | 显示全部楼层
回 @wudixin96
用HTMLFILE对象也是可以的,可是......这东东也是W3C下DOCUMENT模型层次啊,

你的想法不会是那种用MSXML/XMLHTTP读入字符流,再借用HTMLFILE解析出网页模型?
强调快捷XML读取数据流没什么,这个这个,再套上DOCUMENT往下GETTAGS、GETELEMENTS,避开了字符解析,但不觉得绕回来了么,还是要用DOCUMENT对象

本来绕回来也没关系,黑猫白猫,能用就行
我个人认为,对新手与其走MSXML又套上HTMLFILE得到DOCUMENT,直接读取IEAPPLICATION.DOCUMENT 应该更直接罢。

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-8-8 23:15 | 显示全部楼层
0wchz 发表于 2014-8-8 17:08
谢谢学习了Document.all.tags("td")那这是什么对象,如何加到你的代码里?

这是“DOCUMENT下的所有TD集合”,直接解释,是取得网页(DOCUMENT这个文档)下属一切TABLE 单元格对象集。

用这个解析的话,可以得到本页一切表格元素(不管有几张表,一张表的网页最合适),但在具体的应用中,有时可能达不到需求,比如这个TD集合的某个TD,究竟属于哪个TABLE,还有某个表的一系列TD,它们的行列关系是什么——就是纯粹TD集合没有了上级TABLE、行列定位信息。

TA的精华主题

TA的得分主题

发表于 2014-8-8 23:36 来自手机 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
楼主看看我的帖子呗:
http://club.excelhome.net/forum.php?mod=viewthread&tid=1143790&extra=&ordertype=1&threads=thread
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-22 04:40 , Processed in 0.045995 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表