|
论坛上经常有朋友在网页表格数据抓取方面求取,呃...... 多集中于股票和彩票,这方面个人不是很感兴趣,不过仅从代码的角度,还是可以说说的
读取网页有数据流方式(XMLHTTP)和对象模式,各有利弊,这里拿网页对象模型说说,因为数据流的话,提析数据往往要用到正则解析之类的字串分析,初学的朋友眼都会花掉吧。
附件是完成的一个VBA,主程序SAMPLE,有两个例子,一个是本论坛VBA页面,另一个是在HAO123找的股票表格
附件的代码见后面,这里只说说原理,理解了灵活运用。
代码的主要部分是下面那个getTableByNumber函数,调用方式是- CALL getTableByNumber(网页地址,网页上要抓取的表格编号,要把数据导出的RANGE对象)
复制代码 首先假设你已经对打开IE APPLICATION对象已经了解了,这部分不讲(以前发过相关OX),总之是创建InternetExplorer.Application,等它完全打开,最后关掉这个APPLICATION
我们从Set tableX = Ie.document.getElementsByTagName("table")(TableNumber) 这一行开始讨论
在网页的DOCUMENT模型中,TABLE是标准的网页元素,因此它可以用上一级网页元素的getElementsByTagName方法取得所有TABLE的集合- 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,并不是说一定要用这种格式,各位朋友请在理解以后,灵活运用- Option Explicit
- Sub sample()
- Dim myUrl As String, myTableNumber As Integer
- Dim shtX As Worksheet, rngX As Range
-
- '指定网页URL
-
- 'myUrl = "http://www.hao123.com/stocknew"
- 'myTableNumber = 0 '<==第一张表是0号表,依次类推
-
- myUrl = "http://club.excelhome.net/forum-2-1.html"
- 'myTableNumber = 0 '<==第一张表是0号表,依次类推
-
- '指定网页上的表格编号,自已在网页源里测试
- myTableNumber = 4 '<==第一张表是0号表,依次类推
-
- '设置要显示网页内容的目标位置,这里是在第一张表的A2
- Set shtX = ThisWorkbook.Worksheets(1)
- Set rngX = shtX.Range("a2")
-
- shtX.Cells.ClearContents
- Call getTableByNumber(myUrl, myTableNumber, rngX)
- End Sub
- Sub getTableByNumber(Optional Url As String, Optional TableNumber As Integer, Optional rngX As Range)
- Dim Ie
-
- Set Ie = CreateObject("InternetExplorer.Application")
-
- With Ie
- .Visible = True '<==自定,调试时可设为显示
- .navigate Url
-
- Do Until .readyState = 4
- DoEvents
- Loop
- End With
-
- Dim docX, tableX, row, tdGroup
- Dim I, J
-
- Set tableX = Ie.document.getElementsByTagName("table")(TableNumber) '<==网页所有表格的集合
-
- '遍历此表的所有行,TD标签.
- '在此说明一下TABLE相关属性,ROWS是行数,COLS是列数
- '网页集合的计数是从0开始
- For I = 0 To tableX.rows.Length - 1
-
- Set row = tableX.rows(I)
- '遍历每行所有表格
- For J = 0 To row.Cells.Length - 1
-
- '显示内容,注意在EXCEL里RANGE集合取表格位是从1开始,所以要加1
- rngX.Cells(I + 1, J + 1) = row.Cells(J).innerText
- Next
- Next
- Ie.Quit
- End Sub
复制代码 |
|