Java实现仿淘宝滑动验证码研究代码详解

所属分类: 软件编程 / java 阅读数: 81
收藏 0 赞 0 分享

通过下面一张图看下要实现的功能,具体详情如下所示:

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

模拟人为搜索商品

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

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

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;
} 

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();
}
} 

截取网页的某个区域:

/// <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();
}
} 

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

更多精彩内容其他人还在看

Java基于反射机制实现全部注解获取的方法示例

这篇文章主要介绍了Java基于反射机制实现全部注解获取的方法,结合实例形式分析了java反射机制获取注解的具体实现方法与操作注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

Java 信号量Semaphore的实现

这篇文章主要介绍了Java 信号量Semaphore的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

eclipse+maven+spring mvc项目基本搭建过程

这篇文章主要介绍了eclipse+maven+spring mvc项目基本搭建过程,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Spring boot集成swagger2生成接口文档的全过程

这篇文章主要给大家介绍了关于Spring boot集成swagger2生成接口文档的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

Java冒泡排序法和选择排序法的实现

这篇文章主要介绍了Java冒泡排序法和选择排序法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Spring Cloud Alibaba教程之Sentinel的使用

这篇文章主要介绍了Spring Cloud Alibaba教程之Sentinel的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Josephus环的四种解法(约瑟夫环)基于java详解

这篇文章主要介绍了Josephus环的四种解法(约瑟夫环)基于java详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Java继承Thread类创建线程类示例

这篇文章主要介绍了Java继承Thread类创建线程类,结合实例形式分析了java线程操作相关使用技巧与注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

Java使用Callable和Future创建线程操作示例

这篇文章主要介绍了Java使用Callable和Future创建线程操作,结合实例形式分析了java使用Callable接口和Future类创建线程的相关操作技巧与注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

springBoot使用JdbcTemplate代码实例

这篇文章主要介绍了springBoot使用JdbcTemplate代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多