和12306是一样的,运行一张图上点击多个位置,横线以上和左边框还有有边框位置不允许点击,点击按钮输出坐标集合,也就是12306登陆的时候,需要向后台传递的参数。
二、实现思路
1、获取验证码图片
首先,我们看12306登陆页面,F12,通过如图的位置,我们可以观察到,验证码的请求URL是“https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&0.8291445260649148”,
我不知道0.8291445260649148这一串数字是如何得到的,所以,先把它从里面去掉,,只留下“https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand”,
写一个Request请求,发现,可以请求到验证码图像,并且每次都不一样,因此,这段URL就够了。
图片的大小一直都是293*190,这是为了方便拿取坐标。
2、分析验证码图片
通过在12306官网的点击,可以发现,横线以上的部分是不让点击的,左侧和右侧的空白部分也不让点击,那我们在做的时候,就需要选取一个范围,作为鼠标可点击的范围。
通过GetPosition方法,可以轻松的获取到中心图片的四个角的坐标为(5,40)(5,180)(288,40)(288,180)也就是说,我们的可点击区域就是5=<X<=288 && 40=<Y<=180。
这样的话,我们在触发鼠标点击实践的时候,判别Position是否在这个范围。
3、鼠标点击,打上铁老大的Logo
在鼠标点击验证码的时候,将铁老大的Logo打上去,其实很简单,就是给Logo设置一个Canvas的附加属性,但是需要注意的是,我们默认打上去的时候,并不是Logo的中心位置,而是左上角位置,因此,还要计算中心
比如,我的Logo是32*32的,也就是说Position.X-16,Position.Y-16,这样,才能保证Logo上去以后,是中心为鼠标点击的位置。
当点击Logo时,Logo从Canvas里移除掉,这样就可以实现点击取消的效果。
<Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Canvas x:Name="cav" Grid.Row="0"> <Image x:Name="img" Height="190" Width="293" MouseLeftButtonDown="img_MouseLeftButtonDown" /> </Canvas> <Button Grid.Row="1" Content="坐标集合" x:Name="btn" Click="btn_Click" /> </Grid>
private void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { BitmapImage imageIcon = new BitmapImage(new Uri(@"pack://application:,,,/12306SecurityCode;component/favicon.ico", UriKind.RelativeOrAbsolute)); System.Windows.Point pointImg = e.GetPosition(img); System.Windows.Point pointCav = e.GetPosition(cav); if (pointImg.X >= 5 && pointImg.X <= 288 && pointImg.Y >= 40 && pointImg.Y <= 180) { System.Windows.Controls.Image imgIco = new System.Windows.Controls.Image() { Source = imageIcon }; imgIco.MouseLeftButtonDown += ImgIco_MouseLeftButtonDown; Canvas.SetLeft(imgIco, pointCav.X - 16); Canvas.SetTop(imgIco, pointCav.Y - 16); cav.Children.Add(imgIco); ImgicoList.Add(imgIco); } }
private void ImgIco_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { System.Windows.Controls.Image imgico = (System.Windows.Controls.Image)sender; cav.Children.Remove(imgico); ImgicoList.Remove(imgico); }
4、获取剩下的Logo位置