php登录抓取网页指定内容(AHK官网上关于web自动化操作的资料和代码齐全了)
优采云 发布时间: 2021-10-16 16:23php登录抓取网页指定内容(AHK官网上关于web自动化操作的资料和代码齐全了)
再注:本文作者彪悍小轩(),原发表于AHKCN群分享。主要内容虽然适用于当时的AutoHotkey Classical版本,但仍有部分内容具有参考意义,故经作者授权稍作格式调整后转发于此。
其实AHK官网有一套完整的关于网页自动运行的资料和代码,但是由于没有整理出一个完整的文档,也没有集成到帮助文件中,所以很多人一直不知道怎么操作。在开始这篇文章之前,我在官网推荐了 Basic Webpage Controls with JavaScript/COM(作者:jethrow)。如果你的英语能力不错,可以去看看。这篇文章基本上是对官方文章文章的解释和延伸。
建立COM编程环境
在开始学习之前,我们需要建立一个COM编程开发环境。需要的应用有:autohotkey v1.0.48.05, COM.ahk, ACC.ahk 以及用ahk写的一个小工具ahk_web_recorder.ahk,在测试ahk_l时,最新版本ahk_l 也是必需的。COM.ahk和ACC.ahk是编程中需要用到的ahk标准库。下载后需要放在ahk安装目录下的lib目录下。什么是标准库,请参考ahk帮助文件中的标准库部分。
ahk_web_recorder.ahk是一个非常好用的ahk工具,功能和AU3 spy一样,只是用来查找网页上的控制信息,方便我们接下来的编程。也可以用ahk编译成exe。需要指出的是 ahk_web_recorder.ahk 本身也是由 COM.ahk 和 ACC.ahk 两个标准库实现的,所以需要安装 COM.ahk 和 ACC.ahk 才能使用这个程序。
从一个完整的登录实例开始
在开始讲解web操作之前,先举一个百度登录的例子,用五种语言编写:vbs、js、ahk、ahk_l、au3。希望大家可以比较一下语法上的差异,然后学习如何在这些语言之间进行转换。如果在网上看到其他语言写的脚本,用ahk可以快速实现。
vbs版百度登录示例(将以下代码另存为test.vbs,双击查看运行效果):
代码:
set obj = WScript.CreateObject("InternetExplorer.Application") '创建一个IE对象
obj.Visible=true '设置IE为可见
obj.Navigate("https://passport.baidu.com/?login&tpl=mn") '打开百度登录页面
While obj.ReadyState 4 '等待网页加载完成
Wend
obj.document.getElementById("username").value = "ahk_test" '输入用户名
obj.document.getElementById("normModPsp").value = "qwe123" '输入密码
obj.document.all(137).click '点击登录按钮
js版百度登录示例(以下代码另存为test.js,双击查看运行效果):
代码:
obj = new ActiveXObject("InternetExplorer.Application"); //创建一个IE对象
obj.Visible=true; //设置IE为可见
obj.Navigate("https://passport.baidu.com/?login&tpl=mn"); //打开百度登录页面
while (obj.ReadyState != 4){;} //等待网页加载完成
obj.document.getElementById("username").value = "ahk_test" //输入用户名
obj.document.getElementById("normModPsp").value = "qwe123" //输入密码
obj.document.all(137).click() //点击登录按钮
PS:JS严格区分大小写,如果是调用对象的方法,不管有没有参数,都必须加"()",如果是属性,就不要加"() ”。
AHK经典版百度登录示例(有点复杂):
代码:
COM_Init() ;初始化COM组件
pwb := COM_CreateObject("InternetExplorer.Application") ;创建一个IE对象
COM_Invoke(pwb,"Visible",1) ;设置IE为可见
COM_Invoke(pwb,"Navigate","https://passport.baidu.com/?login&tpl=mn") ;打开百度登录页面
While COM_Invoke(pwb,"ReadyState") 4 ;等待网页加载完成
{}
COM_Invoke(pwb,"document.getElementById(username).value","ahk_test") ;输入用户名
COM_Invoke(pwb,"document.getElementById(normModPsp).value","qwe123") ;输入密码
COM_Invoke(pwb,"document.all(137).click") ;点击登录按钮
COM_Release(pwb) ;释放pwb对象
COM_CoUninitialize() ;卸载COM组件
AHK_L版百度登录示例(很简单):
代码:
pwb := ComObjCreate("InternetExplorer.Application")
pwb.Visible := 1
pwb.Navigate("https://passport.baidu.com/?login&tpl=mn")
while pwb.ReadyState 4
{}
pwb.document.getElementById("username").value := "ahk_test"
pwb.document.getElementById("normModPsp").value := "qwe123"
pwb.document.all(137).click()
AutoIt3版百度登录示例(类似VBS的语法):
代码:
$pwb = ObjCreate("InternetExplorer.Application")
$pwb.Visible = 1
$pwb.Navigate("https://passport.baidu.com/?login&tpl=mn")
while $pwb.ReadyState 4
WEnd
$pwb.document.getElementById("username").value = "ahk_test"
$pwb.document.getElementById("normModPsp").value = "qwe123"
$pwb.document.all(137).click()
上面的代码虽然使用了不同的语言,但是大体的过程还是差不多的。我把流程总结为以下几个步骤: 分步操作详解
如何获取 InternetExplorer.Application 对象
这里有两种方法: 关于新建一个InternetExplorer.Application,上面已经有例子了,这里不再赘述。下面说一下从已经启动的浏览器中获取 InternetExplorer.Application 对象。
下面提供了ahk baisc版本的几个函数来获取现有的InternetExplorer.Application对象:
1.IE_Get(win_title); 使用窗口标题获取对象(仅支持IE)
代码:
IEGet( name="" )
{
IfEqual, Name,, WinGetTitle, Name, ahk_class IEFrame ; Get active window if no parameter
Name := ( Name="New Tab - Windows Internet Explorer" ) ? "about:Tabs" : RegExReplace( Name, " - (Windows|Microsoft) Internet Explorer" )
oShell := COM_CreateObject( "Shell.Application" ) ; Contains reference to all explorer windows
Loop, % COM_Invoke( oShell, "Windows.Count" ) {
If pwb := COM_Invoke( oShell, "Windows.item[" A_Index-1 "]" )
If ( COM_Invoke( pwb, "LocationName" ) = name && InStr( COM_Invoke( pwb, "FullName" ), "iexplore.exe" ) )
Break
COM_Release( pwb ), pwb := ""
}
COM_Release( oShell )
Return, pwb
}
2.IE_GetPwb(hwnd); 使用浏览器控件的句柄获取对象(支持IE内核的浏览器,如:世界之窗、旅行、IE等)
注意这里用的是控件的句柄,不是浏览器主窗口的句柄
;;测试说明:激活浏览器正在浏览的页面,按Alt+1查看msgbox的输出结果。如果有值,则表示pwb获取成功。
代码:
COM_Init()
Return
!1::
MouseGetPos, xpos, ypos,, hCtl, 3
msgbox % IE_GetPwb(hCtl)
Return
IE_GetPwb(hWnd)
{
Static
If Not pfn
pfn := DllCall("GetProcAddress", "Uint", DllCall("LoadLibrary", "str", "oleacc.dll"), "str", "ObjectFromLresult")
, msg := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT")
, COM_GUID4String(iid, "{00020400-0000-0000-C000-000000000046}")
If DllCall("SendMessageTimeout", "Uint", hWnd, "Uint", msg, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 1000, "UintP", lr:=0) && DllCall(pfn, "Uint", lr, "Uint", &iid, "Uint", 0, "UintP", pdoc:=0)=0
if(pdoc)
{
pwb := COM_QueryService(pdoc ,"{332C4427-26CB-11D0-B483-00C04FD90119}")
}
Return pwb
}
3. IE_GetPwbByUrl(hwnd="",url=""); 使用浏览器的窗口句柄和标签url获取对象(支持IE核心的多标签浏览器,如:世界之窗、旅行、IE等)。适用于多标签浏览器的后台窗口操作,强烈推荐使用(需要com.ahk和acc.ahk库文件)。
代码:
!1::
WinGet,hwnd,ID,A
msgbox % Return IE_GetPwbByUrl(hwnd,"http://www.autohotkey.com/forum/viewtopic.php?t=30599&highlight=ie7")
Return
IE_GetPwbByUrl(hwnd="",url="")
{
if(!hwnd)
win := "A"
Else
win := "ahk_id " . hwnd
WinGet, ControlList, ControlListhWnd, %win%
;msgbox % controlList
ACC_Init()
Loop, Parse, ControlList, `n
{
; Get the class name of the current control
WinGetClass, ThisWinClass, ahk_id %A_LoopField%
; If the class name is correct and it is a window, it should support JS execution
If (ThisWinClass = "Internet Explorer_Server") && (DllCall("IsWindow", UInt, A_LoopField))
{
IID_IHTMLWindow2 := "{332C4427-26CB-11D0-B483-00C04FD90119}"
pacc := ACC_AccessibleObjectFromWindow(A_LoopField)
pwin := COM_QueryService(pacc,IID_IHTMLWindow2,IID_IHTMLWindow2)
if(!url)
{
rv := pwin
break
}
Else if( COM_Invoke(pwin, "document.url") = url)
{
rv := pwin
break
}
}
}
COM_Release(pacc)
Return rv
}
设置网页可见,浏览器定位到对应页面
参考上面给出的源代码,已经实现了5种语言。
等待页面加载
前面的代码已经给出了方法,适用于阻塞访问。此外,此链接提供了实现 COM 事件的方法,适用于异步操作。这里不再介绍。
操作网页上的控件
IE 上的控件与应用程序的控件不同,AU3_Spy 无法检测到。需要使用ahk_web_recorder.ahk来辅助编程。
在实践中自动化网页操作
下面以百度登录为例,讲解简单网页自动登录的操作方法。
输入帐号
首先用鼠标在“账户”输入框中设置焦点,观察iWebBrowser2窗口的输出。
百度登录页面:关注【账号】输入框。
通过iWebBrowser2,我们可以在“账号”输入框中获取如下信息:
索引=107 名称=用户名id=用户名
因此,相应地,我们有以下三种方法来设置文本框的内容(其实远不止三种,这里只是最基本的方法,其他方法可以参考DOM编程资料) 以上是js代码,可以如上图方便地在浏览器的地址栏中进行测试。对应的ahk经典版代码如下。pwb 对象的获取如上例所示。
可以看到对应的ahk_l版本的代码,ahk_l的操作更像是在做COM编程--!,所以推荐大家使用ahk_l版本。不过下面的例子还是在ahk经典版中给出的,毕竟比较复杂。
其实也可以直接通过ahk调用js语句,比如:
COM_Invoke(pwb,"execscript", "javascript:document.all[107].value='ahk_test'")
效果是一样的,可以测试js语句或者vbs语句,直接使用。
在上面的例子中,方法一是使用控件的索引来获取对象,方法二是使用控件的名称来获取对象。请注意,元素不是元素。方法三是通过控件的ID获取对象,注意是Element。这三个属性可以通过 iWebBrowser2 轻松获取。其中,只有Index属性绝对不是空值。实际上,这两个属性都可能为null,因此无法使用相应的方法。
熟悉DOM的朋友可以使用其他方法来获取控件的对象,但最终通过.value属性设置控件的内容是一样的。
输入密码
让我们用同样的方法查看“密码”文本框。
百度登录页面:关注【密码】输入框。
“密码”文本框有index=111id=normModPsp,没有name属性。
那么我们就无法通过上面的方法2获取到对象了。下面是基于index和id操作的js代码。这里不再给出ahk代码。如果读者从正面看到这个,他应该可以自己完成转换。
记住登录状态
然后操作“记住我的登录状态”复选框。
百度登录页面:关注【记住我的登录状态】复选框。
image005.png (5.49 KiB) 查看 55185 次
索引=128name=mem_passid=mem_pass
操作“记住我的登录状态”复选框的js代码为: 另外,还可以使用click()方法。点击登录
最后,让我们点击“登录”按钮。
百度登录页面:关注【登录】按钮。
发现只有一个索引属性。那么操作代码是:
Javascript:document.all[137].click()
这样就完成了整个登录过程。