自动上网抓数据的机器人[3]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 hsn1982 的 blog

 

    方法1c:使用ras

    ras 是微软的远程访问服务(remote access service)api集合。其中的 api函数rasdial可完成拨号任务。但由于该函数在使用上略显复杂而不太常用,故示例程序中未采纳。

    自动拨号方法小结:rnaui方法使用起来最简单,又由于它不一定非要使用默认连接,因此也最灵活。但这种灵活恰恰又给它带来了弱点,即如果不提供连接名,该方法不会自动调用默认连接。此外,这种方法还有两个最大的缺点:一是仅拨号一次,若出现占线或没有响应等情况时不会自动重试;二是调用程序不容易得到拨号是否成功的返回值。相比之下,wininet方法虽仅能拨打默认连接(无默认连接时,使用第一个连接),但它可多次试拨,并且internetautodial函数等待拨号成功或所有试拨结束以便给调用程序返回拨号是否成功的值,因此,在“自动上网机器人”的环境中wininet方法是最适宜的。

2. 检查在线状况

    方法2a:wininet方法

    若internetgetconnectedstate函数返回true,则为在线状态。该方法最大的缺点是:若当前连接不是用wininet方法建立的,则返回值可能不准确。

    方法2b:查找窗口法

    拨号连接成功后,下图所示的窗口一定存在(不管它是最小化在任务栏的最右端,或是开启为下图所示的状态):

      用findwindow api函数找到该窗口即意味着当前在线。此外,查找窗口法的另一个用处是查找“重新连接”窗口:当中途掉线时,操作系统往往会询问你是否重新连接,找到该窗口并发出模拟“回车”按键即可实现再拨号。

    查找窗口法的缺点是:由于找窗口时需要提供窗口标题,因此即使使用的是默认连接也必须事先知道默认连接名。

    方法2c:ras 方法

    先用rasenumconnections函数返回整个ras集合,再用rasgetconnectstatus函数判断第一个 ras连接的状态。ras方法的最大优点是:不管当前连接是否是用wininet建立的,ras 方法均可对在线状态做出正确判断。

    方法2d:注册表法

    在线时,注册表的“\hkey_local_machine\system\currentcontrolset\services\remoteaccess”处有键值“remote connection”,且其值不为零;不在线时,该处无“remote connection”键值(当本次系统启动后从未拨号成功时),或者其值为零(表明曾拨号成功,但现在已断掉)。

  检查在线状况之方法小结:由于wininet方法的局限性,一般我们应避免使用之;查找窗口法是可靠的,只是要知道连接名;因此我们推荐使用ras 方法和注册表法。

3. 自动挂断

    方法3a:wininet法

  使用internetautodialhangup函数。同样地,若当前连接不是用wininet方法建立的,则返回值可能不准确(即不能成功挂断)。

    方法3b:窗口查找法

  找到图九所示的窗口,然后用showwindow api函数使之成为当前窗口,最后发出模拟<alt>+c的按键操作(从图九中可以看出,<alt>+c是“断开连接”按键的快捷方式)。

    方法3c:ras 法

  用rashangup函数执行挂断。不管用何种方法建立的连接,ras 法均能可靠地完成任务。

  自动挂断方法小结:相比之下,窗口查找法和ras 法是可以信赖的。

4. 本部分总结

  综上所述,对于“自动拨号”、“检查在线状况”、以及“自动挂断”的各种方法,我们推荐“1a-2c-3c”组合。当然各方法可综合使用(如加入2d、3b等),以确保万无一失。在具体编程时还应注意:拨号后判断结果,如不成功应重新拨号;任务进行过程中定时检查在线状态,出现掉线后应及时处理;最后的挂断操作后应再查在线状态,以确保挂断成功。

    下面是实例程序的完整代码。源代码中的全局定义已按照wininet、ras、注册表等进行分类,各具体方法也均按序排列,以便于大家挑选使用。该程序的执行情况在本部分的开始处已给出(图六)。

' 程序三:自动拨号、自动挂断以及自动处理中途掉线
'
option explicit
' 有关 wininet 的全局定义
private const internet_autodial_force_unattended = 2
private const internet_connection_modem = 1
private declare function internetautodial lib "wininet.dll" _
(byval dwflags as long, byval dwreserved as long) as long
private declare function internetautodialhangup lib _
"wininet.dll" (byval dwreserved as long) as long
private declare function internetgetconnectedstate lib _
"wininet.dll" (byref lpdwflags as long, byval _
dwreserved as long) as long
' 有关“窗口查找”的全局定义
private declare function findwindow lib "user32" _
alias "findwindowa" (byval lpclassname as string, _
byval lpwindowname as string) as long
private declare function showwindow lib "user32" _
(byval hwnd as long, byval ncmdshow as long) as long
private const sw_show = 5
' 有关 ras 的全局定义
private const rascs_done = &h2000&
private const ras_maxentryname = 256
private const ras_maxdevicetype = 16
private const ras_maxdevicename = 128
private type rasconn
dwsize as long
hrasconn as long
szentryname(ras_maxentryname) as byte
szdevicetype(ras_maxdevicetype) as byte
szdevicename(ras_maxdevicename) as byte
end type
private type rasconnstatus
dwsize as long
rasconnstate as long
dwerror as long
szdevicetype(ras_maxdevicetype) as byte
szdevicename(ras_maxdevicename) as byte
end type
private ras_buf(255) as rasconn
private ras_status as rasconnstatus
private lpcb as long
private lpcconnections as long
private declare function rasenumconnections lib _
"rasapi32.dll" alias "rasenumconnectionsa" (lprasconn _
as any, lpcb as long, lpcconnections as long) as long
private declare function rasgetconnectstatus lib _
"rasapi32.dll" alias "rasgetconnectstatusa" (byval _
hrasconn as long, lprasconnstatus as any) as long
private declare function rashangup lib "rasapi32.dll" _
alias "rashangupa" (byval hrasconn as long) as long
' 有关“注册表”的全局定义
private const hkey_local_machine = &h80000002
private declare function regopenkey lib "advapi32.dll" alias _
"regopenkeya" (byval hkey as long, byval lpsubkey as _
string, phkresult as long) as long
private declare function regqueryvalueex lib "advapi32.dll" _
alias "regqueryvalueexa" (byval hkey as long, byval _
lpvaluename as string, byval lpreserved as long, lptype _
as long, lpdata as any, lpcbdata as long) as long
private declare function regclosekey lib "advapi32.dll" _
(byval hkey as long) as long
dim ret as long
'自动拨号
private sub wininet拨号测试_click()
if internetautodial(internet_autodial_force_unattended, 0) _
then msgbox "已连接(wininet法)"
end sub
private sub rnaui拨号测试_click()
ret = shell("rundll32.exe rnaui.dll,rnadial " + text1, 1): doevents
sendkeys "{enter}", true: doevents
end sub
'检查是否断线
private sub wininet方法_click() ' wininet法检查是否断线
if internetgetconnectedstate(internet_connection_modem, 0) then
msgbox "在线."
else
msgbox "当前未连接。"
end if
end sub
private sub 查找窗口法_click() ' 查找窗口法检查是否断线
ret = findwindow("#32770", "重新连接")
if ret <> 0 then
call showwindow(ret, sw_show)
sendkeys "{enter}", true: exit sub
end if
ret = findwindow("#32770", "连接到 the95963")
if ret <> 0 then
msgbox "在线."
else
msgbox "当前未连接。"
end if
end sub
private sub ras方法_click() ' ras方法检查是否断线
ras_buf(0).dwsize = len(ras_buf(0)) + 1
lpcb = 256 * ras_buf(0).dwsize
ret = rasenumconnections(ras_buf(0), lpcb, lpcconnections)
if ret then
msgbox "出错!": exit sub
end if
ras_status.dwsize = len(ras_status) + 2
ret = rasgetconnectstatus(ras_buf(0).hrasconn, ras_status)
if ret = 0 and ras_status.rasconnstate = rascs_done then
msgbox "在线."
else
msgbox "当前未连接。"
end if
end sub
private sub 注册表法_click() ' 注册表法检查是否断线
dim subkey as string, valuename as string
dim data as long, result as long
subkey = "system\currentcontrolset\services\remoteaccess"
ret = regopenkey(hkey_local_machine, subkey, result)
if ret = 0& then
valuename = "remote connection"
ret = regqueryvalueex(result, valuename, 0&, 0&, byval data, 0&)
ret = regqueryvalueex(result, valuename, 0&, 0&, data, len(data))
if ret = 0& and data <> 0 then
msgbox "在线!"
else
msgbox "当前未连接。"
end if
regclosekey (result)
end if
end sub
'自动挂断
private sub wininet法_click() ' wininet法自动挂断
if internetautodialhangup(0) then msgbox "已挂断(wininet法)"
end sub
private sub 窗口查找法_click() ' 窗口查找法自动挂断
ret = findwindow("#32770", "连接到 the95963")
if ret <> 0 then
call showwindow(ret, sw_show)
sendkeys "%c", true
msgbox "已挂断(窗口查找法)"
end if
end sub
private sub ras法_click() ' ras法自动挂断
ras_buf(0).dwsize = len(ras_buf(0)) + 1
lpcb = 256 * ras_buf(0).dwsize
ret = rasenumconnections(ras_buf(0), lpcb, lpcconnections)
if ret then
msgbox "出错!": exit sub
end if
ras_status.dwsize = len(ras_status) + 2
ret = rasgetconnectstatus(ras_buf(0).hrasconn, ras_status)
if ret = 0 and ras_status.rasconnstate = rascs_done then
if rashangup(ras_buf(0).hrasconn) = 0 then _
msgbox "已挂断(ras法)"
end if
end sub

本文关键:WebBrowser,拨号
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top