滑动验证码研究-后续

前言(100天做了一件事):

记得在几个月前写过一篇博客,淘宝滑动验证码研究 ,不少的园友对代码比较感兴趣。我也把源码发放给了2位比较聊的来的朋友。不过现在已经又升级了。^_^

这篇博客写了一个后记,估计当时也没什么人留意。我把这博客的后记截个图(这篇博客是3月7号写的,今天是6月27号,刚好100天)

现在我就来介绍些软件的其它功能。希望大家有所受益。

模拟人为搜索商品

在刷单的时候,不能直接拿到一个商品网址就进入购买页面吧,得模拟人为搜索。

在这一个过程中有两个难点:

1)商品列表的异步加载 ;   2)翻页并且截图;

在园子里,我就不在关公面前耍大刀了。直接上代码

i:搜索商品,并且翻页

public bool? SearchProduct(TaskDetailModel taskDetailData)
{
    bool? result = null;
    bool isIndex = true;
    bool isList = true;
    WebBrowserTask.Instance.SetProperties();
    WebBrowserTask.Instance.ClearDocumentCompleted();
    WebBrowserTask.Instance.DocumentCompleted += (wbSenderSearch, wbESearch) =>
    {
        System.Windows.Forms.WebBrowser currentWB = wbSenderSearch as System.Windows.Forms.WebBrowser;
        System.Windows.Forms.HtmlDocument currentDoc = currentWB.Document;
        mshtml.HTMLDocument currentDom = currentDoc.DomDocument as mshtml.HTMLDocument;
        String wbUrl = wbESearch.Url.ToString();
        if (currentWB.ReadyState == System.Windows.Forms.WebBrowserReadyState.Complete)
        {
            #region 首页搜索
            if (wbUrl.Contains("www.taobao.com"))
            {
                if (isIndex == true)
                {
                    isIndex = false;

                    taskDetailData.DetailRemark = String.Format(@"输入关键字""{0}""搜索商品……", taskDetailData.TaskName);

                    Func<bool> func = () =>
                    {
                        bool asynctag = false;
                        System.Threading.Thread.Sleep(5000);
                        asynctag = true;
                        return asynctag;
                    };
                    func.BeginInvoke((ar) =>
                    {
                        bool asyncresult = func.EndInvoke(ar);
                        if (asyncresult)
                        {
                            System.Windows.Forms.HtmlElement heee = currentDoc.GetElementById("J_SearchTab");
                            String classname = heee.GetAttribute("classname");
                            System.Windows.Forms.HtmlElement hitem = heee.Children[0];
                            System.Windows.Forms.HtmlElementCollection heclis = hitem.Children;
                            System.Windows.Forms.HtmlElement li1 = heclis[0];
                            System.Windows.Forms.HtmlElement li2 = heclis[1];
                            System.Windows.Forms.HtmlElement li3 = heclis[2];

                            foreach (System.Windows.Forms.HtmlElement li in heclis)
                            {
                                String liclass = li.GetAttribute("classname");

                                if (liclass.Contains("selected"))
                                {
                                    System.Windows.Forms.HtmlElement q = currentDoc.GetElementById("q");
                                    System.Windows.Forms.HtmlElement btnsearch = currentDoc.GetElementById("J_TSearchForm").Children[0].Children[0];
                                    if (q != null && btnsearch != null)
                                    {
                                        q.Focus();
                                        q.SetAttribute("value", taskDetailData.TaskName);
                                        btnsearch.Focus();
                                        string savePath = Path.Combine(UserData.WorkBenchDirectory, taskDetailData.TaskDetailCode, String.Format("搜索提交.jpg", ""));
                                        CaptureImage.CaptureWebPageArea(currentDom, savePath);
                                        btnsearch.InvokeMember("click");
                                    }
                                }
                            }
                        }
                    },
                    null);
                }

            }
            #endregion 首页搜索

            #region  商品列表
            if (wbUrl.Contains("s.taobao.com"))
            {
                if (isList == true)
                {
                    isList = false;
                    Func<bool> func = () =>
                    {
                        bool asynctag = false;
                        asynctag = true;
                        return asynctag;
                    };
                    func.BeginInvoke((ar) =>
                    {
                        bool asyncresult = func.EndInvoke(ar);
                        if (asyncresult)
                        {
                            //解析每页商品
                            String clickProductURL = TurningAndParsePage(currentDoc, taskDetailData);
                            result = true;
                        }
                    },
                    null);
                }
            }
            #endregion  商品列表
        }

    }; //DocumentCompleted结束

    System.Windows.Application.Current.Dispatcher.Invoke(new System.Action(() =>
    {
        WebBrowserTask.Instance.Navigate("https://www.taobao.com/");
    }));

    for (int i = 0; i < 120; i++)
    {
        System.Threading.Thread.Sleep(1000);
        if (result != null)
        {
            break;
        }
    }
    return result;
}
View Code

ii:因为每个页面都是异常加载的,选择适当的时机对网页进行截图
截取整个网页:

/*
    因为包含了控件,如果在了线程里调用,必须用Invoke方法
    System.Windows.Application.Current.Dispatcher.Invoke(new System.Action(() =>
{
    //htmlDoc.Window.ScrollTo(new System.Drawing.Point(5000, htmlDoc.Body.ScrollRectangle.Height));
    string savePath = string.Format(@"D:\{0}.jpg", Guid.NewGuid().ToString());
    CaptureImage.CaptureWebPage(webBrowserTask, savePath);
}), System.Windows.Threading.DispatcherPriority.Background);
    */
/// <summary>
/// 截取整个网页
/// </summary>
/// <param name="web"></param>
/// <param name="savePath"></param>
public static void CaptureWebPage(System.Windows.Forms.WebBrowser web, String savePath)
{
    Rectangle body = web.Document.Body.ScrollRectangle;
    Rectangle docRectangle = new Rectangle()
    {
        Location = new Point(0, 0),
        Size = new Size(body.Width, body.Height)
    };
    web.Dock = DockStyle.None;
    web.Width = docRectangle.Width;
    web.Height = docRectangle.Height;
    Rectangle imgRectangle = docRectangle;

    using (Bitmap bitmap = new Bitmap(imgRectangle.Width, imgRectangle.Height))
    {
        IViewObject ivo = web.Document.DomDocument as IViewObject;

        using (Graphics g = Graphics.FromImage(bitmap))
        {
            IntPtr hdc = g.GetHdc();
            ivo.Draw(1, -1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, hdc, ref imgRectangle, ref docRectangle, IntPtr.Zero, 0);
            g.ReleaseHdc(hdc);
        }
        bitmap.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
        bitmap.Dispose();
    }
}
View Code

截取网页的某个区域:

/// <summary>
/// 截取网页的一部份
/// </summary>
/// <param name="htmlDom"></param>
/// <param name="savePath"></param>
public static void CaptureWebPageArea(mshtml.HTMLDocument htmlDom, String savePath)
{
    String saveDir = System.IO.Path.GetDirectoryName(savePath);
    if (!System.IO.Directory.Exists(saveDir))
    {
        System.IO.Directory.CreateDirectory(saveDir);
    }

    Rectangle docRectangle = new Rectangle()
    {
        Location = new Point(0, 0),
        //Size = new Size(htmlDom.body.offsetWidth, htmlDom.body.offsetHeight)
        Size = new Size((int)System.Windows.SystemParameters.PrimaryScreenWidth, (int)System.Windows.SystemParameters.PrimaryScreenHeight)
    };
    Rectangle imgRectangle = docRectangle;

    using (Bitmap bitmap = new Bitmap(imgRectangle.Width, imgRectangle.Height))
    {
        IViewObject ivo = htmlDom as IViewObject;

        using (Graphics g = Graphics.FromImage(bitmap))
        {
            IntPtr hdc = g.GetHdc();
            ivo.Draw(1, -1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, hdc, ref imgRectangle, ref docRectangle, IntPtr.Zero, 0);
            g.ReleaseHdc(hdc);
        }
        bitmap.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
        bitmap.Dispose();
    }
}
View Code

 在这代码里有很多有趣的片段。有心的朋友会发现。

总结

我整个软件已经开发完成。但是我就是不贴上网址。免得有人说我打广告。

哈哈

posted @ 2016-06-27 18:45 Sam Xiao 阅读(...) 评论(...) 编辑 收藏