文章出處

前言(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

 在這代碼里有很多有趣的片段。有心的朋友會發現。

總結

我整個軟件已經開發完成。但是我就是不貼上網址。免得有人說我打廣告。

哈哈


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()