Java實(shí)現(xiàn)仿淘寶滑動驗(yàn)證碼研究代碼詳解
通過下面一張圖看下要實(shí)現(xiàn)的功能,具體詳情如下所示:
現(xiàn)在我就來介紹些軟件的其它功能。希望大家有所受益。
模擬人為搜索商品
在刷單的時候,不能直接拿到一個商品網(wǎng)址就進(jìn)入購買頁面吧,得模擬人為搜索。
在這一個過程中有兩個難點(diǎn):
1)商品列表的異步加載 ; 2)翻頁并且截圖;
在園子里,我就不在關(guān)公面前耍大刀了。
直接上關(guān)鍵代碼:
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(@"輸入關(guān)鍵字""{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結(jié)束 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; }
ii:因?yàn)槊總€頁面都是異常加載的,選擇適當(dāng)?shù)臅r機(jī)對網(wǎng)頁進(jìn)行截圖
截取整個網(wǎng)頁:
/* 因?yàn)榘丝丶?,如果在了線程里調(diào)用,必須用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> /// 截取整個網(wǎng)頁 /// </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(); } }
截取網(wǎng)頁的某個區(qū)域:
/// <summary> /// 截取網(wǎng)頁的一部份 /// </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(); } }
在這代碼里有很多有趣的片段。有心的朋友會發(fā)現(xiàn)。
- java登錄驗(yàn)證碼實(shí)現(xiàn)代碼
- java 圖片驗(yàn)證碼的實(shí)現(xiàn)代碼
- Java實(shí)現(xiàn)驗(yàn)證碼具體代碼
- Java 隨機(jī)生成驗(yàn)證碼(支持大小寫字母、數(shù)字、隨機(jī)字體)的實(shí)例
- JAVA實(shí)現(xiàn)利用第三方平臺發(fā)送短信驗(yàn)證碼
- Java隨機(jī)生成手機(jī)短信驗(yàn)證碼的方法
- java實(shí)現(xiàn)短信驗(yàn)證碼5分鐘有效時間
- JavaWeb簡單用戶登錄注冊實(shí)例代碼(有驗(yàn)證碼)
- Java實(shí)現(xiàn)滑動驗(yàn)證碼的示例代碼
- java實(shí)現(xiàn)隨機(jī)驗(yàn)證碼圖片生成
相關(guān)文章
性能爆棚的實(shí)體轉(zhuǎn)換復(fù)制工具M(jìn)apStruct使用詳解
這篇文章主要為大家介紹了性能爆棚的實(shí)體轉(zhuǎn)換復(fù)制工具M(jìn)apStruct使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Java使用Callable接口實(shí)現(xiàn)多線程的實(shí)例代碼
這篇文章主要介紹了Java使用Callable接口實(shí)現(xiàn)多線程的實(shí)例代碼,實(shí)現(xiàn)Callable和實(shí)現(xiàn)Runnable類似,但是功能更強(qiáng)大,具體表現(xiàn)在可以在任務(wù)結(jié)束后提供一個返回值,Runnable不行,call方法可以拋出異,Runnable的run方法不行,需要的朋友可以參考下2023-08-08揭秘SpringBoot!一分鐘教你實(shí)現(xiàn)配置的動態(tài)神刷新
在今天的指南中,我們將深入探索SpringBoot?動態(tài)刷新的強(qiáng)大功能,讓你的應(yīng)用保持最新鮮的狀態(tài),想象一下,無需重啟,你的應(yīng)用就能實(shí)時更新配置,是不是很酷?跟我一起,讓我們揭開這項(xiàng)技術(shù)如何讓開發(fā)變得更加靈活和高效的秘密吧!2024-03-03SpringBoot實(shí)現(xiàn)IP地址解析的示例代碼
本篇帶大家實(shí)踐在springboot項(xiàng)目中獲取請求的ip與詳細(xì)地址,我們的很多網(wǎng)站app中都已經(jīng)新增了ip地址顯示,具有一定的參考價值,感興趣的可以了解一下2024-01-01Java中ThreadLocal避免內(nèi)存泄漏的方法詳解
ThreadLocal是Java中的一個線程本地存儲機(jī)制,它允許每個線程擁有一個獨(dú)立的本地存儲空間,用于存儲該線程的變量,本文主要介紹了ThreadLocal如何避免內(nèi)存泄漏,需要的朋友可以參考下2023-05-05Java多線程開發(fā)工具之CompletableFuture的應(yīng)用詳解
做Java編程,難免會遇到多線程的開發(fā),但是JDK8這個CompletableFuture類很多開發(fā)者目前還沒聽說過,但是這個類實(shí)在是太好用了,本文就來聊聊它的應(yīng)用吧2023-03-03Springboot項(xiàng)目中運(yùn)用vue+ElementUI+echarts前后端交互實(shí)現(xiàn)動態(tài)圓環(huán)圖(推薦)
今天給大家?guī)硪黄坛剃P(guān)于Springboot項(xiàng)目中運(yùn)用vue+ElementUI+echarts前后端交互實(shí)現(xiàn)動態(tài)圓環(huán)圖的技能,包括環(huán)境配置及圓環(huán)圖前端后端實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧2021-06-06