Java实现仿淘宝滑动验证码研究代码详解
作者:Sam Xiao 发布时间:2022-12-28 00:51:11
标签: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();
}
}
在这代码里有很多有趣的片段。有心的朋友会发现。
0
投稿
猜你喜欢
- 前言开发中,免不了会用到多边形、多角星等图案,比较常用的多边形比如雷达图、多角星比如评价星级的五角星等,本篇文章就使用Flutter绘制封装
- Java虚拟机(JVM)是可运行Java代码的假想计算机。只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java
- 前言:在纯 Java 代码里 我们一般都会用class.getResource(String name) 或者 class.getClass
- Java 实现FTP服务实例详解1、FTP简介 FTP
- 三层架构将整个业务应用划分为:(1)界面UI层(2)业务逻辑层(3)数据访问层对于复杂的系统分层可以让结构更加清晰,模块更加独立,便于维护。
- 本文实例为大家分享了Android自定义view完成车载可调整轨迹线的具体代码,供大家参考,具体内容如下同事做的view,拿过来做个记录。/
- hadoop做的一个简单grep程序,可从文档中提取包含某些字符串的行/* * 一个简单grep程序,可从文档中提取包含莫些字符串
- 前言前段时间在写RPC框架的时候用到了Kryo、Hessian、Protostuff三种序列化方式。但是当时因为急于实现功能,就只是简单的的
- 前言Android 从 4.0 开始就提供了手机录屏方法,但是需要 root 权限,比较麻烦不容易实现。但是从 5.0 开始,系统提供给了
- Spark的算子的分类从大方向来说,Spark 算子大致可以分为以下两类:1)Transformation 变换/转换算子:这种变换并不触发
- 一、IDEA自带打包插件内容:此种方式可以自己选择制作胖包或者瘦包,但推荐此种方式制作瘦包。输出:输出目录在out目录下流程步骤:第一步:
- 一直做Android前端,今天突然心血来潮想搭建一个后台玩玩。平时都是需要什么样的接口直接出个接口文档扔给后台的兄弟,自己从来不操心他们内部
- Android里有两个类android.view.GestureDetectorandroid.view.GestureDetector.S
- springboot引入外部yml配置文件当需要在springboot中引用其他的yml文件时,需要在application.yml里配置s
- 自动生成的代码报错解决办法:把自动xml文件中自动生成的二级缓存注释掉来源:https://blog.csdn.net/weixin_447
- c# 轮询算法这两天做东西,业务上有个特殊的需求,在用户访问页面的时候,针对某一行代码进行控制,按照概率来进行显示,我做的是针对当前页面的曝
- 效果就是这样,RecyclerView列表可拖拽排序,可删除,可添加;RecyclerView给我们提供了一个手势器:ItemTouchHe
- @Configuration注解的类:/** * @Description 测试用的配置类 * @Author 弟中弟 * @CreateT
- Word是我们日常生活、学习和工作中必不可少的文档处理工具。精致美观的文档能给人带来阅读时视觉上的美感。在本篇文章中,将介绍如何使用组件Fr
- 本文实例讲述了Android编程实现分页加载ListView功能。分享给大家供大家参考,具体如下:package eoe.listview;