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

 更新时间:2016年06月28日 10:14:09   作者:Sam Xiao  
这篇文章主要介绍了Java实现仿淘宝滑动验证码研究代码详解的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下

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

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

模拟人为搜索商品

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

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

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实现九宫格拼图游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • mybatis-plus分页查询的实现实例

    mybatis-plus分页查询的实现实例

    页查询是一项常用的数据库查询方法,本文主要介绍了mybatis-plus分页查询的实现实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06
  • Spring Security实现身份认证和授权的示例代码

    Spring Security实现身份认证和授权的示例代码

    在 Spring Boot 应用中使用 Spring Security 可以非常方便地实现用户身份认证和授权,本文主要介绍了Spring Security实现身份认证和授权的示例代码,感兴趣的可以了解一下
    2023-06-06
  • 详解Java 中程序内存的分析

    详解Java 中程序内存的分析

    这篇文章主要介绍了详解Java 中程序内存的分析的相关资料,需要的朋友可以参考下
    2017-04-04
  • JAVA  静态的单例的实例详解

    JAVA 静态的单例的实例详解

    这篇文章主要介绍了JAVA 静态的单例的实例详解的相关资料,这里提供了实例方法,来说名不仅实现了延迟加载,又可以保证线程安全,不影响系统性能,需要的朋友可以参考下
    2017-07-07
  • SpringBoot通过自定义注解实现参数校验

    SpringBoot通过自定义注解实现参数校验

    实现参数校验说实话方式还挺多,个人使用过直接在Controller代码里面写、AOP+自定义注解、ConstraintValidator。本文主要和大家讲的是ConstraintValidator实现,感兴趣的可以了解一下
    2022-12-12
  • Spring AOP与代理类的执行顺序级别浅析

    Spring AOP与代理类的执行顺序级别浅析

    这篇文章主要介绍了Spring AOP与代理类的执行顺序级别,关于 Spring AOP和Aspectj的关系,两个都实现了切面编程,Spring AOP更多地是为了Spring框架本身服务的,而Aspectj具有更强大、更完善的切面功能
    2023-03-03
  • Java中的CompletableFuture使用解析

    Java中的CompletableFuture使用解析

    这篇文章主要介绍了Java中的CompletableFuture使用解析,为什么CompletableFuture要定制化线程池,因为默认的线程池是ForkJoinPool,这个线程池的最大线程数默认是你的电脑的线程数数减1,假如我线程电脑是4核8线程的,ForkJoinPool的最大线程数就是7,需要的朋友可以参考下
    2024-01-01
  • Java实现ip地址和int数字的相互转换

    Java实现ip地址和int数字的相互转换

    这篇文章主要介绍了Java实现ip地址和int数字的相互转换,帮助大家更好的利用Java处理数据,感兴趣的朋友可以了解下
    2020-09-09
  • Java实现上传Excel文件并导入数据库

    Java实现上传Excel文件并导入数据库

    这篇文章主要介绍了在java的基础上学习上传Excel文件并导出到数据库,感兴趣的小伙伴不要错过奥
    2021-09-09

最新评论