第一講,介紹一下基本的東西
如何打開一個網頁,太簡單,加點要求
1,打開百度,http://www.baidu.com , 在百度搜索里面輸入”與 autoit3 親密接觸”,偶的blog;
2,窗口我要”800*600”,隱藏工具欄,而且大小不可更改;
3,偏執一點,不喜歡”百度一下,你就知道”,那我們改一下”我的百度,我做主”
4,狀態欄里面顯示信息”歡迎訪問 與 autoit3 親密接觸 hi.baidu.com/iokey”
5,我不想看到整個過程,我只想看到結果,OK沒問題.
首先我們打開一個瀏覽器,輸入百度的網址,這里要用到_IECreate,這個函數的返回值是指向這個ie窗口的目標變量,參數” 0,1,1,0”,分別的意思是:不找已經存在的www.baidu.com的ie窗口,顯示ie,等待網頁載入完全然后返回,激活此ie窗口
#include <IE.au3>
$oIE = _IECreate ("www.baidu.com",0,1,1,0)
接下來我們對這個窗口進行一番設置,這里要用到_IEPropertySet,這個函數用來設置瀏覽器或者DOM元素的
_IEPropertySet ($oIE, "toolbar", 0) ;隱藏toolbar
_IEPropertySet ($oIE, "width", 800) ;設置ie寬800像素
_IEPropertySet ($oIE, "height", 600) ;設置ie高600像素
_IEPropertySet ($oIE, "resizable", 0) ;設置ie不可以調整大小
_IEPropertySet ($oIE, "title","我打開的百度,我做主") ;設置ie標題,取代原title
_IEPropertySet ($oIE, "statustext","歡迎訪問 與 autoit3 親密接觸 hi.baidu.com/iokey") ;設置狀態欄
設置完畢,我想在搜索框里面寫入搜索內容,這里說明一點,當窗口顯示的時候我們可以用send()/sendx()來發送,但是這樣會遇到一個常見的問題,可能窗口不是激活狀態,因為ie窗口里面的內容不是標准的空間,所以GUICtrlSetData失效了.不過對ie.au3有更好的方法,下面來看:
$oForm = _IEFormGetObjByName ($oIE, "f")
$oQuery1 = _IEFormElementGetObjByName ($oForm, "wd")
_IEFormElementSetValue ($oQuery1, "與 autoit3 親密接觸")
上面三句,分別是找到name為”f”的表單,在這個表單里面找到name為”wd”的表單元素,這里的wd代表的就是搜索框,最后將wd的內容設置為"與 autoit3 親密接觸"
這里還有朋友要問,能不能自動點擊搜索按鈕呢?當然可以的,而且我們還不是通過簡單的send()回車鍵來實現,
_IEFormSubmit ($oForm,0)
這句就是提交$oForm表單, 0代表不等待網頁載入完成立即返回.
這樣還不夠,那我們再玩點花樣,目標是先讓ie隱藏,設置啊,輸入搜索串都是在隱藏狀態下完成,顯示出來的時候什么都完成了,首先我們讓ie打開的時候就是隱藏狀態,
$oIE = _IECreate ("www.baidu.com",0,0,1,0)
然后在適當的時候,我們讓她顯示出來,這里我們用到_IEAction(),這個函數模擬了我們對瀏覽器的大部分操作,如刷新,后退,退出等等,這里是讓ie顯示的,當然也有隱藏的功能.
_IEAction ($oIE, "visible")
總結一下,這里我們用到了幾個函數;_IEPropertySet;_IECreate;_IEAction 這些都是和瀏覽器屬性相關的,有着眾多的參數可以來利用,基本上可以滿足對瀏覽器的操作.這里大家可能要提出一些疑問,在輸入百度搜索內容的時候提到的”f””wd”,是從哪里來的?
這個就留在下一講,將詳細的講述一下如何填寫表單.
本次的完全代碼:
#include <IE.au3>
$oIE = _IECreate ("www.baidu.com",0,0,1,0);打開一個ie,輸入百度網址
_IEPropertySet ($oIE, "toolbar", 0)
_IEPropertySet ($oIE, "width", 800)
_IEPropertySet ($oIE, "height", 600)
_IEPropertySet ($oIE, "resizable", 0)
_IEPropertySet ($oIE, "title","我打開的百度,我做 主")
_IEPropertySet ($oIE, "statustext","歡迎訪問 與 autoit3 親密接觸 hi.baidu.com/iokey")
$oForm = _IEFormGetObjByName ($oIE, "f")
$oQuery1 = _IEFormElementGetObjByName ($oForm, "wd")
_IEFormElementSetValue ($oQuery1, "與 autoit3 親密接觸")
_IEFormSubmit ($oForm,1)
_IEAction ($oIE, "visible")
Sleep(5000)
MsgBox(0,"提醒","確定退出IE")
_IEAction ($oIE, "quit")
第二講,我們開始討論如何填寫表單
第一步,先簡單說一下HTML表單(Form).
HTML表單(Form)是HTML的一個重要部分,主要用於采集和提交用戶輸入的信息。
HTML表單(Form)常用控件有:
input type="text" 單行文本輸入框,可以用來輸入用戶名
input type="password" 密碼輸入框(輸入的文字用*表示)
input type="submit" 將表單(Form)里的信息提交給表單里action所指向的文件,一般我們從網頁上看到的就是確定/發表等等
input type="checkbox" 復選框
input type="radio" 單選框
select 下拉框
textArea 多行文本輸入框
第二步,我們如何找到一個網頁的表單和表單內的控件.
下面我們結合mail.163.com來講解如何自動填寫
這個就是登錄時候我們要操作的幾個部分:分類如下
1,用戶名
2,密 碼
3,版 本 默 認/極速 3.0 /簡 約
4,記住用戶名/增強安全性
5,登錄郵箱/登錄網盤
這個五部分就是163mail里面的表單控件,這里我們先要看一下下面兩個函數
_IEFormGetCollection 返回代表文檔內表單的目標變量的集合,同時@EXTENDED記錄了表單的數量
_IEFormElementGetCollection返回代表指定表單內所有控件的目標變量的集合,同時@EXTENDED記錄了該表單內控件的數量
好的,知道了上面兩個函數的簡單描述,我們可以寫出:
#include <IE.au3>
$oIE = _IECreate ("http://mail.163.com")
$oForms = _IEFormGetCollection ($oIE)
MsgBox(0, "表單信息", "這個頁面上共有" & @extended & "個表單")
這里還要提到一個關鍵字"For...In...Next "這個關鍵字thesnow沒有漢化,我就羅嗦幾句,
For <$Variable> In <expression>
statements
...
Next
<$Variable> 是一個變量,不必事先聲明
<expression>是一個數組或者變量合集(至少包含一個元素)
作用是列舉<expression>的所有元素.
為什么要提到這個呢?
因為_IEFormGetCollection ($oIE)返回的是個合集,$oQuerys = _IEFormElementGetCollection ($oForms)這樣是錯誤的,
而正確的方法是:
For $Form In $oForms
MsgBox(0, "表單名稱", $oForm.name)
Next
這里的$Form是隨意定義的變量,可以是任意的變量,對於表單內的控件也可以同理得到尋找方法,
完整的查看表單的方法就出來了,
$oIE = _IECreate ("http://mail.163.com")
$oForms = _IEFormGetCollection ($oIE)
MsgBox(0, "表單信息", "這個頁面上共有" & @extended & "個表單")
For $Form In $oForms
MsgBox(0, "表單名稱", $Form.name)
$oQuerys = _IEFormElementGetCollection ($Form)
For $Query In $oQuerys
MsgBox(0, "表單控件信息", "名稱:"&$Query.name & " 類型:"&$Query.type)
Next
Next
這里只是找到了這些表單/控件,有時還是難分辨具體對於網頁上是哪部分,有HTML基礎的朋友可以看網頁的源文件,核對,無基礎的朋友建議借助Dreamweaver來看,不是很難.
第三步,我們來讓autoit3填寫這個表單,
先說一下思路,因為我們已經可以通過上面的方法找到相關的資料,可以得到如下信息:
表單:一個 名稱是login163
1,用戶名 : username 類型是text
2,密 碼 :passward 類型是passward
3,版 本: 默 認/極速 3.0 /簡 約 : selType 類型是 select-one
4,記住用戶名/增強安全性 : remuser 類型是 checkbox / secure 類型是 checkbox
5,登錄郵箱/登錄網盤 : 登錄郵箱 類型是 submit / 登錄網盤 類型是 submit
下面我們用到的幾個函數
_IEFormGetObjByName 返回一個表單的變量,這個變量指向指定名稱的表單
_IEFormElementGetObjByName 返回一個控件的變量,這個變量指向指定表單和名稱的控件
_IEFormElementSetValue 設定表單控件的值
接下來我們先試一下,將郵箱的用戶名寫上去:
#include <IE.au3>
$oIE = _IECreate ("http://mail.163.com")
$oForm = _IEFormGetObjByName ($oIE, "login163")
$oQuery = _IEFormElementGetObjByName ($oForm, "username")
_IEFormElementSetValue ($oQuery, "AutoIt IE.au3")
同樣的方法,寫入密碼:
$oQuery = _IEFormElementGetObjByName ($oForm, "password")
_IEFormElementSetValue ($oQuery, "AutoIt IE.au3")
下面是"版本"的選擇了,這要用到下面這個函數:
_IEFormElementOptionSelect 設置 "Select Option"類的表單控件值,具體見幫助.
$oQuery = _IEFormElementGetObjByName ($oForm, "selType")
_IEFormElementOptionSelect ($oQuery , 1, 1, "byIndex")
對應"記住用戶名/增強安全性"這兩個checkbox我們取消check狀態,需要下面的函數:
_IEFormElementCheckBoxSelect 可以設置"checkbox"類的表單控件值,具體見幫助
_IEFormElementCheckboxSelect ($oForm, 0, "", 0, "byIndex")
_IEFormElementCheckboxSelect ($oForm, 1, "", 0, "byIndex")
最后我們還剩下"登錄郵箱/登錄網盤"這兩個選項了,
這里上一章節用來提交表單的函數_IEFormSubmit 使用不了,為什么?"there is often custom JavaScript tied to an onClick event for its Submit button"幫助里面的.
所以我們要用到_IEAction()也是上一章節提到的,我們通過名稱找到對應這個控件的變量,然后模擬一個click在這個變量上,方法如下:
$oQuery = _IEFormElementGetObjByName ($oForm, "登錄郵箱")
_IEAction($oQuery ,"click")
同樣登錄網盤就是下面的方法:
$oQuery = _IEFormElementGetObjByName ($oForm, "登錄網盤")
_IEAction($oQuery ,"click")
終於寫完了,我想綜合一/二兩講,添加一些GUI方面的東西,大家可以寫出一個不錯的163郵件登錄的工具,甚至做出一個多郵箱登錄軟件
總結:
這一講包括的函數:
IEFormElementCheckboxSelect
_IEFormGetObjByName
_IEFormElementGetCollection
_IEFormElementGetObjByName
_IEFormElementOptionSelect
_IEFormElementSetValue
下面這兩個是類似的函數,大家看看幫助就明白了.
_IEFormElementGetValue
_IEFormElementRadioSelect
本次代碼:
#include <IE.au3>
$oIE = _IECreate ("http://mail.163.com",0,0,1,0)
_IEPropertySet ($oIE, "toolbar", 0)
_IEPropertySet ($oIE, "width", 600)
_IEPropertySet ($oIE, "height", 600)
_IEPropertySet ($oIE, "resizable", 0)
$oForm = _IEFormGetObjByName ($oIE, "login163")
$oQuery = _IEFormElementGetObjByName ($oForm, "username")
_IEFormElementSetValue ($oQuery, "AutoIt IE.au3")
$oQuery = _IEFormElementGetObjByName ($oForm, "password")
_IEFormElementSetValue ($oQuery, "AutoIt IE.au3")
$oQuery = _IEFormElementGetObjByName ($oForm, "selType")
_IEFormElementOptionSelect ($oQuery , 1, 1, "byIndex")
_IEFormElementCheckboxSelect ($oForm, 0, "", 0, "byIndex")
_IEFormElementCheckboxSelect ($oForm, 1, "", 0, "byIndex")
$oQuery = _IEFormElementGetObjByName ($oForm, "登錄郵箱")
_IEAction($oQuery ,"click")
sleep(2000)
_IEAction ($oIE, "visible")
第三講 介紹一下點擊鏈接相關的函數
在開始第三講之前,再說一點,就是關於_IEDocWriteHTML 這個函數,我在博客也提到了這個難題,這幾天可能都花在研究相關的內容了,很遺憾目前自己還是沒有搞定.
本講將的函數包括(翻譯不准大家體諒):
_IEImgClick() ;模擬點擊圖片
_IEImgGetCollection () ;返回文檔內所有圖片的集合
_IELinkClickByIndex () ;模擬點擊鏈接,通過從0開始的索引
_IELinkClickByText() 根據用戶提供的字符串,模擬鼠標動作,點擊與之相匹配的文字鏈接。
_IELinkGetCollection () ;返回文檔內所有鏈接的集合
1,關於圖片的,因為網友問了,所以這講里面介紹一下
_IEImgClick() 模仿用戶對圖片的點擊動作,可以通過圖片描述,名稱,鏈接的字符串或者完全鏈接地址,實際應用中可能不大常用.
_IEImgGetCollection () 返回文檔內所有圖片的集合
我們這里舉個例子,通過上面兩個函數做一個簡單的顯示圖片工具:
一個簡單的例子大家如果感興趣可以可以考慮做個批量下載的.
_IEFormImageClick()模擬在此類(<input type=image>)控件上點擊.
#include <IE.au3>
$oIE = _IECreate ("http://www.pcpop.com/pp/133556_557953.html",0,0,1,0)
$oImgs = _IEImgGetCollection ($oIE)
;~ $iNumImg = @extended
;~ MsgBox(0, "Img Info", "There are " & $iNumImg & " images on the page")
For $oImg In $oImgs
If StringInStr($oImg.src,"www.pcpop.com/pp") = 0 And StringInStr($oImg.src,"120x120") = 0 Then
;~ _IECreate($oImg.src,0,1,1,0)
$sInfo = "Src: " & $oImg.src & @CR
$sInfo &= "FileName: " & $oImg.nameProp & @CR
$sInfo &= "Height: " & $oImg.height
$sInfo &= " Width: " & $oImg.width
$sInfo &= " Border: " & $oImg.border & @CR
$sInfo &= "存儲位置: " & @DesktopDir
InetGet($oImg.src,@DesktopDir&"girl.jpg",0,1)
MsgBox(0, "美女圖片信息",$sInfo,8)
EndIf
Next
_IEAction($oIE,"quit")
2,關於鏈接的論壇也有朋友問過,正好發現一個問題,是在使用過程中發現的,
_IELinkClickByText () 在A版中會出錯退出,只能在U版本中使用,這個函數使用方便但是有局限性.
_IELinkClickByIndex () 這個函數實際使用中,如果搭配簡單的例子可以直接寫出相應的參數,而如果在較為復雜的網頁中為了保證正確性最好搭配下面那個函數,
_IELinkGetCollection () 來查找需要的鏈接.
列舉官方幫助例子,基礎例子.
#include <IE.au3>
$oIE = _IE_Example ("basic")
$oLinks = _IELinkGetCollection ($oIE)
$iNumLinks = @extended
MsgBox(0, "Link Info", $iNumLinks & " links found")
For $oLink In $oLinks
MsgBox(0, "Link Info", $oLink.href)
Next
最后說一下一個網友的三個問題,可能大家或許都有疑問,所以解答了一下,歡迎補充意見.
1,form的name不存在(源碼中看的,如果用代碼查詢則為0);那_IEFormGetObjByName 函數不能用了。該如何定位表單?該頁面中有多個這樣的表單。
2,表單中的控件有相同的name,該如何有效地定位控件?
3,如果要抓取頁面上特定的由程序生成的驗證碼圖片(ie緩存中沒有該圖),該如何操作?
期待第三講…………
一位網友提出上面的疑問,我先解答一下:
1,確實存在沒有name的時候,這里先說一個IE.AU3沒提到的一點,就是form的id也可以替代name一項,在應用中可以使用;
如果二者都沒有,那么我們也可以利用_IEFormGetCollection, 其返回值是變量合集,可以列出每個form的目標變量,有了她我們就找到需要的form了.
2,對於相同name的控件,多出現在 (type="radio" value="033" name="rdb_rb")這類情況中,我們可以利用value的不同,來區分
3,看了一些驗證碼圖片都是可以下載的,用_IEImgGetCollection 找到所以,然后找到自己需要的,然后用可以download下來.
ie.au3在網頁中的應用,很大一部分是在針對ie的表單(form)進行操作,ie.au3也提供了相應的函數供我們使用,但是對表單(form)之外的控件或者一些比較特殊無法用和form相關的函數來處理的情況,我們應該怎么做?
本講就是介紹和講解解決上面問題的函數,主要有下面幾個函數:
_IEGetObjById 返回一個目標變量,對應指定的id or name
_IEGetObjByName 返回一個目標變量,對應指定的id or name
_IETableGetCollection 返回指定文檔內所有/指定的表格的目標變量,指定的表單是以索引順序來指定的(0,1,2,3...)
_IETableWriteToArray 讀出表格內的數據,寫入到一個數組,
_IETagNameAllGetCollection 返回指定文檔內所有/指定的標記名(Tagname)的目標變量,指定的標記名是以索引順序來指定的(0,1,2,3...)
_IETagNameGetCollection 返回指定文檔內所有特定標記名的目標變量集.
-----------------------------------------------------------------------------------------------------------------------
_IEGetObjById 返回一個目標變量,對應指定的id or name
_IEGetObjByName 返回一個目標變量,對應指定的id or name
從幫助里面看 _IEGetObjByName 比 _IEGetObjById多了一個參數,這個參數也是在ie.au3里面經常提到的$i_index,
把所有同id or name 的列一個索引(0,1,2,3...),$i_index表示索引的第幾個,以便於我們指定特定的id or name,
函數比較簡單 就說明一下官方的例子
; 下面的例子將"line1"內的"innertext"顯示在控制台(編輯器的output F8顯示隱藏)
; *******************************************************
#include <IE.au3>
$oIE = _IE_Example ("basic")
$oDiv = _IEGetObjById ($oIE, "line1") ;返回一個id為"line1"的div的指向變量,有了這個變量我們可以用_IEPropertyGet/_IEPropertySet對其進行操作
ConsoleWrite(_IEPropertyGet($oDiv, "innertext") & @CR)
;~ MsgBox(0,"",_IEPropertyGet($oDiv, "innertext") & @CR) 個人習慣這種用法.
; *******************************************************
; 下面的方法等同於 $oForm = _IEFormGetObjByName($oIE, "ExampleForm")
; *******************************************************
#include <IE.au3>
$oIE = _IE_Example ("form")
$oForm = _IEGetObjByName
_IETableGetCollection 返回指定文檔內所有/指定的表格的目標變量,指定的表單是以索引順序來指定的(0,1,2,3...)
_IETableWriteToArray 讀出表格內的數據,寫入到一個數組,
這兩個可以收集網頁內的數據,對於數據型的網頁,可以通過這兩個函數很方便的獲取數據.
例子的目的是讀取網頁內所以表格數據,並且顯示出來.
#include <Array.au3>
$oIE = _IECreate ("http://www.autoit.net.cn/search.php?srchfrom=45000&searchsubmit=yes")
$oInputs = _IETableGetCollection ($oIE) ;返回指網頁內所有表格的目標變量
$iNumTables = @extended ;文檔內所以表格的數量
MsgBox(0, "Table Info", "There are " & $iNumTables & " tables on the page")
$i = 0
For $oInput In $oInputs
$table = _IETableGetCollection ($oIE,$i)
$oInput = _IETableWriteToArray ($table) ;讀取指定表格內的數據,寫入到數組
_ArrayDisplay($oInput, "第"&$i+1&"個表單內容",0,1) ;顯示數組
$i += 1
Next
_IETagNameAllGetCollection 返回指定文檔內所有/指定的標記名(Tagname)的目標變量,指定的標記名是以索引順序來指定的(0,1,2,3...)
_IETagNameGetCollection 返回指定文檔內所有特定標記名的目標變量集.
感覺_IETagNameAllGetCollection 的實用性不大,而_IETagNameGetCollection 則相對來講比較有用,
對於網頁里面的某些控件,例如button,無法采用getbyname or getbyid等方式准確找到的時候,可以用tagname來處理,
網頁內的button <INPUT onclick="checkform" type=button value="發 表">
我們可以用下面這種方法來點擊:
$oInputs = _IETagNameGetCollection ($oIE, "INPUT")
For $oInput In $oInputs
if $oInput.value = "發 表" then
_IEAction ($oInput, "click")
EndIf
Next
