Selenium爬虫实战:截取网页上的图片

代码觅月使
• 阅读 3774

前言

同样是为了刷课,没想到工作后依然和大学一样逃脱不了需要刷网课的命运……

正文

直接说干货了,截取图片,需要截取的图片是什么图片大家都懂(说的就是你,验证码),其他图片的话不需要截取,直接拿到地址下载就行,验证码不行,同样的地址再访问一次内容就变了。

我不知道为啥selenium不能直接把特定img元素的图片拿出来,太反人类了。

根据我找到的资料,主要有两种思路,一种是模拟鼠标操作,在验证码上面点击右键,然后选择另存为,把验证码保存到本地之后再来读取…… 我不理解为啥有这种这么思路清奇的操作,右键另存为的一个很大问题就是你根本没法控制图片存在那里,这也导致这个爬虫程序不具备通用性!所以直接pass掉。

另一种是先对整个网页截图,然后再按照验证码img元素的位置和大小,定位并且裁剪出小的验证码图片来,理想情况下是可以的,但是经过我多次测试发现不同浏览器裁剪出来图片有不同偏移和缩放,不知道是哪里出了问题,只能硬编码微调,吐了。尽管方法不完美,但是也勉强够用吧,分享一下代码……

代码

这次是用C#(WinForm)做的,虽然只是代码片段,不过截图+裁剪保存部分还是可以参考一下的。

后面的验证码识别是顺带加上的,用了百度的接口,准确率堪忧。

setStatusMsg1("正在提取验证码");
var verifyCode = currentBrowser.WebDriver.FindElement(By.XPath("/html/body/spk-root/spk-login-page/div/section/div[3]/div[2]/div[2]/form/div[3]/div[2]/img"));
setStatusMsg2("浏览器截屏");
// 设置浏览器大小
currentBrowser.WebDriver.Manage().Window.Size = new Size(1280, 800);
// 浏览器截屏
var screenshot = ((ITakesScreenshot)currentBrowser.WebDriver).GetScreenshot();
var screenImagePath = Path.Combine(Path.GetTempPath(), $"{System.Guid.NewGuid().ToString("N")}.jpg");
// 保存截屏图片
setStatusMsg2("保存截屏");
screenshot.SaveAsFile(screenImagePath, ScreenshotImageFormat.Jpeg);

// 裁剪验证码
setStatusMsg2("裁剪验证码");
var codeImagePath = screenImagePath.Replace(".jpg", "_code.jpg");

int x, y, width, height;

// 使用js来获取图片的位置等信息
switch (currentBrowser.BrowserType) {
    case BrowserEnum.Chrome:
        x = Convert.ToInt32((long)((IJavaScriptExecutor)currentBrowser.WebDriver).ExecuteScript("return document.querySelector('body > spk-root > spk-login-page > div > section > div.login-body.clearfix > div.login-right > div.form-con > form > div.qr-code > div.qrcode-box.clearfix > img').x"));
        y = Convert.ToInt32((long)((IJavaScriptExecutor)currentBrowser.WebDriver).ExecuteScript("return document.querySelector('body > spk-root > spk-login-page > div > section > div.login-body.clearfix > div.login-right > div.form-con > form > div.qr-code > div.qrcode-box.clearfix > img').y"));
        width = verifyCode.Size.Width;
        height = verifyCode.Size.Height;
        // 验证码位置调整
        //x += 20;
        //y += 8;
        // 验证码大小调整
        width += 30;
        height += 15;
        break;
    default:
        x = verifyCode.Location.X;
        y = verifyCode.Location.Y;
        width = verifyCode.Size.Width;
        height = verifyCode.Size.Height;
        break;
}

var codeBitmap = new Bitmap(width, height);
var codeGraphics = Graphics.FromImage(codeBitmap);

var destRec = new Rectangle(0, 0, width, height);
var srcRec = new Rectangle(x, y, width, height);
setStatusMsg2(srcRec.ToString());
codeGraphics.DrawImage(new Bitmap(screenImagePath), destRec, srcRec, GraphicsUnit.Pixel);
// 保存验证码图片
codeBitmap.Save(codeImagePath, ImageFormat.Jpeg);

// 显示图片
picVerifyCode.Load(codeImagePath);
picVerifyCode.Tag = codeImagePath;

// 验证码识别
var result = BaiduAiSdk.VerifyCode(codeImagePath);
if (result.Length > 0) {
    txtVerifyCode.Text = result;
    FrmTips.ShowTipsSuccess(this, $"验证码识别成功,识别结果:{result}");

    var input = currentBrowser.WebDriver.FindElement(By.XPath("/html/body/spk-root/spk-login-page/div/section/div[3]/div[2]/div[2]/form/div[3]/div[2]/input"));
    input.Clear();
    input.SendKeys(result);
} else
    FrmTips.ShowTipsError(this, "验证码识别失败,请重试!");

参考资料

欢迎交流

程序设计实验室专注于互联网热门新技术探索与团队敏捷开发实践,在公众号「程序设计实验室」后台回复 linux、flutter、c#、netcore、android、kotlin、java、python 等可获取相关技术文章和资料,同时有任何问题都可以在公众号后台留言~

Selenium爬虫实战:截取网页上的图片

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
javaCV
  最近有视频处理的需求,自己调研javaCV。  官网没有详细的API,各种轮子翻遍了也没找到几个有用的,以下是自己整理一些视频处理功能:截取视频指定帧生成gif,将图片旋转指定度,截取视频指定帧保存为指定格式的图片(图片保存在视频同文件夹下),_调整视频清晰度(只能降低),_视频转音频__。  先上代码。packagecom.ric
浩浩 浩浩
4年前
【Flutter实战】图片和Icon
3.5图片及ICON3.5.1图片Flutter中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。ImageProviderImageProvider是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvi
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
JavaScript常用函数
1\.字符串长度截取functioncutstr(str,len){vartemp,icount0,patrn/^\x00\xff/,strre"";for(vari
马尚 马尚
1年前
使用JavaScript解决网页验证码识别的全流程详解
网页验证码是网站常用的一种安全手段,用于验证用户身份或者防止恶意机器人访问。本文将介绍使用JavaScript解决网页验证码识别的全流程,包括下载验证码图片、预处理图片、调用第三方识别接口、模拟填写表单等步骤,并提供详细的代码示例。1.下载验证码图片首先,
马尚 马尚
1年前
使用JavaScript解决网页验证码识别的全流程详解
网页验证码是网站常用的一种安全手段,用于验证用户身份或者防止恶意机器人访问。本文将介绍使用JavaScript解决网页验证码识别的全流程,包括下载验证码图片、预处理图片、调用第三方识别接口、模拟填写表单等步骤,并提供详细的代码示例。1.下载验证码图片首先,
马尚 马尚
1年前
使用JavaScript解决网页验证码识别的全流程详解
网页验证码是网站常用的一种安全手段,用于验证用户身份或者防止恶意机器人访问。本文将介绍使用JavaScript解决网页验证码识别的全流程,包括下载验证码图片、预处理图片、调用第三方识别接口、模拟填写表单等步骤,并提供详细的代码示例。1.下载验证码图片首先,
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
代码觅月使
代码觅月使
Lv1
日落君山云起,春到沅湘草木,远思渺难收。
文章
4
粉丝
0
获赞
0