`
ciiiiiii
  • 浏览: 832 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

网页自动化,美味的甜点

阅读更多
如果不是用在工作,掌握的技能还能有什么用吗?做了这么些年coder,总算为自己做了个有用的东东。
场景:
某个网站,不定时会有超低价的宝贝发售。是不是想买呀,那得时刻候着,不停的刷新页面。
我洗刷刷呀洗刷刷,总算等到可以开始发售了。点击购买,弹出页面"您所需要的宝贝已售完",算了么,不,我得想个法折腾一下。
来吧,网页自动化。开始工作,只见页面不停的刷新,等到变成可购买状态。
马上自动填好数量,唰唰唰完成购买流程。
这个用处多着呢,类似于制造业机器人替代人工吧。
-----------------------------------------------------------------
一些实现经历:
访问网页
只要实现了http协议都能获取到页面。不过大部分时候都是需要浏览器的功能,执行页面的各项动作。
浏览器控件需要显示出完整的页面,耗费的时间就比较长。
这样在只是单纯获取数据时,就是用http协议控件。执行的时候再用webbrowser控件。

先说说http控件
这个只用到最基本的获取功能。
获取过来的html页面需要解析。找现成的解析代码,解析成便于访问的DOM格式。


webbrowser控件
一些基础的操作。
1)网页加载周期
一般处理页面都需要等页面加载完成才能操作。 
但这个控件从开始加载到加载完成,并没有提供明确的加载完成标记。
由于其中涉及到frame的加载等,判断起来也不太直观。
查阅了一些资料。摘录了一个,用用也还凑合。

2)分析页面
有些页面包含frame,相当于一个页面集合。
这样就需要获取到每个frame,才能对其元素进行操作。

3)获取html元素
webbrowser提供了根据名字查找的接口。
这远远不够,所以一般就需要遍历所有页面元素。
然后根据特定属性来定位元素。
如果有特别复杂的字符匹配那用正则表达式是不错的选择、

4)执行动作
  一般对页面的进行的各项动作。
  填写输入框-给IHTMLInputElement.value 赋值就可以了。
  点击-执行IHTMLElement.click; 
  执行页面的js脚本-- 执行 IHTMLWindow2.execScript(script,'javascript') ;

其它用到的操作:
1)获取图像
  网页经常需要输入验证码,要进行验证码识别,那首先得提取验证码图像。
  识别有难度,这也是网页自动化碰到的一个坎。
 

2)确认弹出框
  页面会弹出一些windows的确认窗口。需要及时的点击确认。

 
3)卷滚动条和模拟点击操作。
本身页面元素是带有点击方法的。
但有次碰到个现象。用<a>标记的click方法和手工点击这个标签,最后跳转的页面地址会有区别。
产生原因不详。这时就需要模拟点击的方法。

4)网页的缓存
浏览器具有缓存机制,这样刷新一个页面的时候就可能得不到最新的状态。
查阅了一些资料。
一是用webbrowser.refrensh2(REFRESH_COMPLETELY),强制刷新接口。
二是用webbrowser.navigate(url+random),通过给地址加上随机参数来避免缓存。
个人碰到的情况不多,不太确定是不是适应所有情况。
--------------------------------------------------------------------
网页的监测分析
要完成自动化,分析出网站的结构那是基本任务。
我是用火狐的firebug工具来分析网站的结构。




付上代码。
-----------------网页加载等待-----------------
function  WaitWebPageLoad(wb:TWebBrowser;timeOut:integer):boolean;
var
  i,j:integer;
begin
  result:=false;
  i:=0;
  j:=0;
  while true do
  begin
    if wb.ReadyState=READYSTATE_COMPLETE then
    begin
      if (not wb.Busy) then
      begin
        i := i + 1;
        if (i=2) then
        begin
          result:=true;
          exit;
        end;
      end else
        i:=0;
    end;
    Delay(100);
    inc(j);
    if j>timeOut then
      exit;
  end;
end;
procedure  Delay(Millisecond:integer);
var
  current :TDateTime;
begin
  current := Now;
  while (IncMilliSecond(current,Millisecond) > Now) do
  begin
    Application.ProcessMessages;
  end;
end;
-----------------获取frame页面-----------------
function GetFrame(doc:Ihtmldocument2;FrameNo:Integer):IWebbrowser2;
var
  OleContainer:IOleContainer;
  enum:IEnumUnknown;
  unk:IUnknown;
  Fetched:PLongint;
begin
  Fetched:= nil;
  OleContainer:= doc as IOleContainer;
  OleContainer.EnumObjects(OLECONTF_EMBEDDINGS,enum);
  Enum.Skip(FrameNo);
  Enum.Next(OLECONTF_EMBEDDINGS,Unk,Fetched);
  Result:=Unk as IWebbrowser2;
end;


-----------------获取图像-----------------
procedure getHtmlImage(doc:Ihtmldocument2;Element:IHTMLElement);
var
  rang:IHTMLControlRange;
  Img:IHTMLControlElement ;
begin
  try
    rang:=((doc.body as HTMLBody).createControlRange) as IHTMLControlRange;
    Img:= Element as  IHTMLControlElement;
    rang.add(Img);
    rang.execCommand('Copy',False,0);
  except
  end;
end;

--------------模拟点击操作--------------
procedure TMainFrm.clickelement(wb:TWebBrowser;Element: IHTMLElement);
var
  HtmlRect:IHtmlRect;
begin
  HtmlRect:=(Element as  IHTMLElement2).getBoundingClientRect;
  memo1.Lines.Add(format('left-%d right-%d top-%d bottom-%d' ,[HtmlRect.left,HtmlRect.right,HtmlRect.top,HtmlRect.bottom]));

  (wb.Document as ihtmldocument2).parentWindow.scrollTo(0,HtmlRect.top-50);

  HtmlRect:=(Element as  IHTMLElement2).getBoundingClientRect;
  memo1.Lines.Add(format('left-%d right-%d top-%d bottom-%d' ,[HtmlRect.left,HtmlRect.right,HtmlRect.top,HtmlRect.bottom]));

  clickBrowser(wb,HtmlRect.left,HtmlRect.top);

end;


procedure TMainFrm.clickBrowser(wb: TWebBrowser; left, top: integer);
var
  wParam,lParam:integer;
  className:Pchar;
  Capacity:integer;
  whandle:Thandle;
begin
  getmem(className,200);
  zeromemory(className,200);
  whandle:= wb.Handle ;
  GetClassName(whandle, className, 200);
  while (className<> 'Internet Explorer_Server') and (whandle<>0) do
  begin
    whandle:=GetWindow(whandle,5);
    zeromemory(className,200);
    GetClassName(whandle, className, 200);
  end;

  lParam:= ((top shl 16) or left);
  wParam:=0;
  SendMessage( whandle, WM_MOUSEMOVE , wParam, lParam); // Mouse button down
  SendMessage( whandle, WM_LBUTTONDOWN , wParam, lParam); // Mouse button down
  SendMessage( whandle, WM_LBUTTONUP, wParam, lParam); // Mouse button up
end;
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics