|
楼主 |
发表于 2008-12-5 10:45
|
显示全部楼层
dmt.all.tags("table")
这个tags也有函数原型
Function tags(tagName) As object
看它的返回值就知道 它也傻,但它只有一个参数,所以傻不过 dmt.all(xx,yy)
Sheet1.Pictures(2).Left = 0 这句代码你如果能理解,可以跳过下面这一段
为了方便理解 先回到工作表界面
新建一个工作簿 在sheet1上画一个按钮 然后通过菜单栏插入随便 2到3幅图片
如果想通过代码移动第二幅图片到最左边 常用得写法 有以下4种
[图片 1].left = 0 或 Evaluate("图片 1").left = 0 或 Shapes("图片 1").left = 0
或 Shapes(3).left = 0 (Shapes(1)是先画的那个按钮 )
但 Pictures(2).Left = 0 也是一样。 Pictures是隐藏的方法、属性 表示所有插入的图片,并可用序号表示单一的图片
同样 先画上去的“按钮 1”也可以用 Buttons(1) 来表示,类似的隐藏的方法属性还有不少,可以通过对象浏览器查看
Picture, Button 就相当于TagName 不过在网页上叫法有点不一样: FORM IMG INPUT A B DIV FONT TABLE 等等
表达方式 通过tags 来引用 dmt.all.tags("INPUT")(0).TEXT = "ldy" 在第一个个输入框里输入用户名
网页的序号从 0 算起 ,这个跟工作表从1 算起有点不同
Value、Text、innertext、outertext
对象的文字,根据类型反映在不同的属性
如果要填写页面,在输入框里输入类似 11111111
AAAAAA BBBBBBBB 88888888888888 这样的字
然后再全部分析,再在 分析 表里查找,很容易就能定位那些输入框的 名称,
这样就能确定到底是用 T.value= "ldy" 还是用 T.text= "ldy"
nameProp 通常用来表示子路径
sourceIndex 对象在网页中唯一序号。
Set T = dmt.all(123)
但用这个序号固定写入程序里太不靠谱。
每次刷新都可能不同。某些网页甚至会插入不少的空节点,来打乱原来的序号
(用这种方法来防止代码读取页面资料,不过对于本文读者来说,哈哈哈。。。)
href 对象链接的完整路径。
分析网页常用的属性 也差不多了,还可以用parentElement 取得上级对象 用 children childNodes取得下级对象
dmt.all(xx,yy) 和 dmt.all.tags(tagname)(index) 两个语句已经能够从 序号 ID Name 类型 4 个方面分析处理网页上的所有对象了
通常在网页上取值 也就是 对 Value、Text、innertext、outertext 这4个属性取值
用 href 属性来获取链接地址
说了这么多 那些tagname ID name 如何得到? 对啊 咱还有工具啊
介绍一下咱的小工具
工作原理就是把页面上的所有对象都过一遍,把常用的属性值显示在工作表上。
说穿了就是把本地窗口中看到的内容节选出来,平面化显示,便于分析
还可以进一步细化 通过“指定 tags 分析” 可以选择 只分析 “Table”
还可以 通过“指定ID、Name分析” 可以选择 只分析 某个ID 或 名称
工作表上有ActiveCell, 页面上同样有activeElement 就是被点中(有焦点)的的对象 可以通过“activeElement简介” 了解 ID 、Name
序号 和 类型(tagname),如果是文本框直接点进去就行,但如果是个按钮或是个链接,点它的话会打开链接
同时也就失去焦点了,这里操作上有个小技巧,不要用左键去点,用右键点,对于弹出的右键菜单不用理会,这样既选中了按钮,
又不会打开链接。这时再去点击“activeElement简介”按钮 就会看到相关的信息, 这个对于填写、提交页面非常有用
具体操作
在分析表中 点击按钮打开窗体。
地址栏里是一个 百度股票行情的地址,就以此为例吧,直接按回车键 ,等页面完全打开。
点 全部分析 按钮,大概等几秒钟吧,分析表上列出了700多行数据,在看看页面上,内容很丰富,但我们想要的就是那张表格里的东西
700多行,那些是我需要的? 用EXCEL的查找功能 按 ctrl+f 调出查找框 输入 在页面表格上看到的任何一个股票名称,然后逐一查找
你会发现很多单元格里都有这个 股票名称 ,有些事一大堆文字包含很多无用信息,有些仅有这一只股票的全部信息,不全
1600301南化股份4.16 4.20 4.15 - 4.58 4.58 10.10% 30102 1365 10.34%
看看它的 tagname --> 是 TR ,VBA的类型是 HTMLTableRow,Row ??很熟悉啊 记住了以后有用,再看下一行的 VBA类型
是 HTMLTableCell,Cell ?? 这个更熟悉了。
继续查找,找到了这个单元格里有那个表上的的 列标题和全部内容,一点多余的东西都没有,纯的,哈哈就它了。
"序号代码股票名称昨收盘今开盘今低 - 今高当前价涨跌幅成交量金额振幅相关
1600301南化股份4.16 4.20 4.15 - 4.58 4.58 10.10% 30102 1365 10.34%
2600844丹化科技13.52 13.83 13.72 - 14.87 14.87 9.99% 30357 4340 8.51%
3600543莫高股份8.04 8.04 8.00 - 8.84 8.84 9.96% 40968 3560 10.45%
4600070浙江富润3.83 3.80 3.80 - 4.21 4.21 9.92% 28934 1179 10.70%
5600452涪陵电力3.94 4.17 4.17 - 4.33 4.33 9.90% 15570 672 4.06%
6600505西昌电力3.44 3.55 3.55 - 3.78 3.78 9.88% 34011 1282 6.69%
7600208新湖中宝3.42 3.49 3.45 - 3.74 3.69 7.89% 314349 11239 8.48%
8600285羚锐股份4.57 4.55 4.46 - 5.03 4.90 7.22% 101748 4889 12.47%
9600088中视传媒9.85 9.60 9.59 - 10.80 10.44 5.99% 92506 9614 12.28%
10600739辽宁成大13.25 13.20 13.18 - 14.58 14.03 5.89% 301154 43172 10.57%
11600425青松建化5.20 5.22 5.08 - 5.50 5.50 5.77% 22820 1214 8.08%
12600251冠农股份25.23 25.29 25.29 - 27.37 26.62 5.51% 36248 9589 8.24%
13600808马钢股份3.90 3.90 3.87 - 4.12 4.11 5.38% 190525 7677 6.41%
14600021上海电力3.55 3.62 3.62 - 3.88 3.74 5.35% 101182 3822 7.32%
15600382广东明珠4.97 4.97 4.97 - 5.25 5.23 5.23% 34268 1764 5.63% "
看看它的 tagname --> 是 TABLE ,VBA的类型是 HTMLTable,Table ??不就是表格的意思吗,但它的innertext中的数据全都紧贴在一起
如果编个自定义函数去拆分它,想着就头痛。刚才都"熟悉"两回了,要是还没有点联想,唉。。。保重吧…………
现在用指定tags分析,看那网页上有多少个 table,点击“清空分析结果”按钮,在左边第一个列表框里选中table,点击指定tags分析
按钮,这次很快,分析表上的2--7 行列出了6个table的信息中发现第 5 个就是所需要的table,在分析表的第6行
这里有一个简单的减法 ,用不着从0数下来, 所在行号-2 就是它在 集合里的序号 你要想把这个 table set 到一个 变量里
就该这样 set T = dmt.all.tags("table")(4) 这是分析完以后写道程序里的,现在还不用。
看看它的sourceIndex 是286(当前是,过几分钟或下次再打开这个页面就不一定是了,所以说它 不靠谱,这个页面会自动刷新)
现在要用到“指定序号分析”了,看到这个按钮了吗? 下面有一个文本框,输入286 点击“指定序号分析”
这时 自动切换到的代码界面,要从本地窗口中看看这个T 都有什么东西了。
你没有本地窗口?? 你一定是初学者,那你太幸运了,要是我在初学VBA的时候能看到这样一篇文章,估计我现在都会飞了。
别不好意思,我也是学VBA半年后才会在 代码界面 的 视图菜单 中找到用 本地窗口 的,又过了3个月才明白它的妙处。
本地窗口中 看到一个 T 前面有个+号,点击+号展开………… 100 多个属性,都是按字母顺序排列的,先找熟悉的吧,
很快,看到个 cells 属性,前面也有个+号,点开,看到length属性(相当于VBA中的count)=192,下面跟着 Item1到 Item192,
前面也都有个+号 。这个表 16行 12 列 16*12可不就等于 192,还是要编个函数去去拆分??
对了,还有个熟人 row,刚才cell 变cells 那row不会也变成 rows吧? 果然有个rows 点开+号 length =16 刚好16 行,跟着item1-16
点开item1的+号,又是100多属性,再次见到熟人,也有cells 点开+号 length = 12 嘿嘿,刚好12列,跟着item1-12 再点开 item1的+号
又是一堆属性,怎么老是这么多属性,看吧,……
看到 "序号"了 ,又看到"序号",又看到"序号",好几个地方都写着"序号",回头瞄了一眼网页上的那个表,第1行第1列 正是 "序号"
至此 这个table的中的有用数据是如何存放的 都搞清楚了,其他数据用两个循环嵌套就像在工作表中取值一样。一串简洁高效的代码出现了
Set dmt = WebBrowser1.Document
Set R = dmt.all.tags("table")(4).Rows
For i = 0 To R.Length - 1
For j = 0 To R(i).Cells.Length - 1
Sheet3.Cells(i + 1, j + 1) = R(i).Cells(j).innerText
Next
Next
我们分析出来dmt.all.tags("table")(4) 就是所需要的数据,百度是大公司,通常不会去改变这个结构。但如果是其他公司的网页,
可能会增加广告、通知什么的,就有可能增加table的数量,今天 dmt.all.tags("table")(4) ,明天4就可能要改成5 或 6
对这种变化较频繁的页面,就要用循环判断table的特征来确定到底是 4 还是 5 或 6 ,这样可以延长代码的有效期。
像这个表可以用文字特征来判断。
Set dmt = WebBrowser1.Document
for i = 0 to dmt.all.tags("table").length - 1
if instr(dmt.all.tags("table")(i).innertext,"序号代码股票名称") > 0 then x = i
Next
Set R = dmt.all.tags("table")(x).Rows
For i = 0 To R.Length - 1
For j = 0 To R(i).Cells.Length - 1
Sheet3.Cells(i + 1, j + 1) = R(i).Cells(j).innerText
Next
Next' 在工具文件窗体上有这个例子
table 是网页中的主要元素,几乎每个网页都有,刷新页面总元素数量可能变化,但table的数量一般不会变。
对于网页分析,没有任何绝对的东西,上面这段代码的有效期 取决于百度何时更改table的特征。比如那天百度疯了,序号不叫序号
改叫名次,这是涨幅榜叫名次也没错,代码 给加两个字 叫 股票代码, 股票名称 给减两个字 叫名称,那我们也只好修改判断语句了。
最后 注意多Froms的网页,你需要的数据可能在其中一个Forms里,通过Set R = dmt.all(index) 不一定能取到值
这时需要 Set R = dmt.Forms(2).all(index) 其他的语法方法不变
写这些东西太累,暂时打住吧,一般的网页通过上述这些方法可以无障碍的读取操作了。
网页分析工具.rar
(53.56 KB, 下载次数: 5488)
老的附件中有一些测试时的引用,并不起作用,在某些电脑上报错,下面这个是修正过的。
网页分析工具.rar
(28.51 KB, 下载次数: 10033)
附录1 不弹出新窗口,在原窗口显示页面
- Private Sub WebBrowser1_NewWindow2(ppDisp As Object, Cancel As Boolean)
- Cancel = True
- WebBrowser1.Navigate2 WebBrowser1.Document.activeElement.href
- End Sub
复制代码 ' 直接把WebBrowser的silent设置成true就没有脚本错误提示了...
WebBrowser1.Silent = True
最近很多坛友问起网页中框架的问题,其实并不难,简单整理如下
关于多框架页面的分析、引用
这个工具是个单页面分析工具,对于嵌套的框架 分析结果以一个 FRAME 对象表示
要对框架中的内容操作需要继续分析,下面是几个常用语法
L = WebBrowser1.Document.frames.length '页面中有几个框架
set dmt1= WebBrowser1.Document.frames(0).Document '取得第一个 子框架的文档对象
s = WebBrowser1.Document.frames(0).location '子框架的地址 相当于右键 单击属性
可以通过这个子网址 继续分析。
分析后的完整引用语法: WebBrowser1.Document.frames(0).Document.all("input").value = "ldy"
2009-7-18
百度的页面已调整,
Private Sub UserForm_Initialize() 中的语句
TextBox40 = "http://stock.baidu.com/cn/sort_all.php?sh_sz=0&isB=0&order=-10&PageNo=1"
请照此修改
TextBox40 ="http://baidu.hexun.com/stock/sort_all.php?sh_sz=0&isB=0"
[ 本帖最后由 ldy 于 2008-12-5 11:01 编辑 ]
[ 本帖最后由 ldy 于 2009-6-6 17:31 编辑 ]
[ 本帖最后由 ldy 于 2009-7-18 17:56 编辑 ]
[ 本帖最后由 ldy 于 2009-11-4 17:34 编辑 ] |
评分
-
7
查看全部评分
-
|