共计 3326 个字符,预计需要花费 9 分钟才能阅读完成。
前言
同样是为了刷课,没想到工作后仍然和大学一样逃脱不了须要刷网课的命运……
注释
间接说干货了,截取图片,须要截取的图片是什么图片大家都懂(说的就是你,验证码),其余图片的话不须要截取,间接拿到地址下载就行,验证码不行,同样的地址再拜访一次内容就变了。
我不晓得为啥 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, "验证码辨认失败,请重试!");
参考资料
- Python +Selenium 解决图片验证码登录或注册问题:https://www.mscto.com/python/…
- python 网课主动刷课程序 -selenium+chromedriver:https://kaiwu.lagou.com/java_…
- selenium 之 定位以及切换 frame/iframe:https://blog.csdn.net/huilan_…
- Python 爬虫利器五之 Selenium 的用法:https://cuiqingcai.com/2599.html
欢送交换
程序设计实验室专一于互联网热门新技术摸索与团队麻利开发实际,在公众号「程序设计实验室」后盾回复 linux、flutter、c#、netcore、android、kotlin、java、python 等可获取相干技术文章和材料,同时有任何问题都能够在公众号后盾留言~
- 博客园:https://www.cnblogs.com/deali/
- 打代码直播间:https://live.bilibili.com/11883038
- 知乎:https://www.zhihu.com/people/dealiaxy
正文完