我有注册网页,但最后验证码显示..
我无法从图像中读取文字。我要提一下代码和输出..
@Test
public void loginTest() throws InterruptedException {
System.out.println("Testing");
driver.get("https://customer.onlinelic.in/ForgotPwd.htm");
WebElement element = driver.findElement(By.xpath("//*[@id='forgotPassword']/table/tbody/tr[5]/td[3]/img"));
System.out.println(" get the instance ");
String elementTest = element.getAttribute("src");
System.out.println("Element : " + elementTest);
}
输出:错误
线程“main”中的异常org.openqa.selenium.NoSuchElementException: 无法找到元素: { “方法”: “的xpath”, “选择器”: “// [@ ID = 'forgotPassword'] /表/ tbody的/ TR [5] / TD [3] / IMG”} 命令持续时间或超时:60.02秒有关此错误的文档,请访问: http://seleniumhq.org/exceptions/no_such_element.html构建信息: 版本:'2.35.0',修订版:'8df0c6b',时间:'2013-08-12 15:43:19' 系统信息:os.name:'Windows 7',os.arch:'amd64',os.version: '6.1',java.version:'1.6.0_26'会话ID: 5f5b2e1a-56a4-49ad-8fd3-2870747a7768驱动程序信息: org.openqa.selenium.firefox.FirefoxDriver Capabilities [{platform = XP, acceptSslCerts = true,javascriptEnabled = true,browserName = firefox, rotate = false,locationContextEnabled = true,version = 23.0.1, cssSelectorsEnabled = true,databaseEnabled = true,handlesAlerts = true, browserConnectionEnabled = true,nativeEvents = true, webStorageEnabled = true,applicationCacheEnabled = true, takeScreenshot = true}] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法) 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 在 org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:191) 在 org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145) 在 org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:554) 在 org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:307) 在 org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:404) 在org.openqa.selenium.By $ ByXPath.findElement(By.java:344)at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:299) 在seleniumtest.CaptchaTest.loginTest(CaptchaTest.java:41)at seleniumtest.CaptchaTest.main(CaptchaTest.java:59)引起: org.openqa.selenium.remote.ErrorHandler $ UnknownServerException:无法使用 找到元素: { “方法”: “的xpath”, “选择器”: “// [@ ID = 'forgotPassword'] /表/ tbody的/ TR [5] / TD [3] / IMG”} 构建信息:版本:'2.35.0',修订版:'8df0c6b',时间:'2013-08-12 15:43:19'系统信息:os.name:'Windows 7',os.arch:'amd64', os.version:'6.1',java.version:'1.6.0_26'驱动程序信息: driver.version:未知.FirefoxDriver.prototype.findElementInternal_(file:/// C:/Users/lukup/AppData/Local/Temp/anonymous4043037924964932185webdriver-profile/extensions/fxdriver@googlecode.com/components/driver_component.js:8880 ) at .fxdriver.Timer.prototype.setTimeout /< .notify(file:/// C:/Users/lukup/AppData/Local/Temp/anonymous4043037924964932185webdriver-profile/extensions/fxdriver@googlecode.com/components/driver_component.js :396)
答案 0 :(得分:6)
只是为了详细说明以前的答案,CAPTCHA作为“完全自动公共图灵测试告诉计算机和人类分开”的首字母缩写。 所以,如果“机器”可以解决它,那就不是真正的工作。
为了解决这个问题,你可以做些事情 - 使用外部服务的API,例如http://www.deathbycaptcha.com。 您实现他们的API,将CAPTCHA传递给他们并获得文本。我观察到的平均解算时间约为10-15秒。
实施示例(摘自here)
import com.DeathByCaptcha.AccessDeniedException;
import com.DeathByCaptcha.Captcha;
import com.DeathByCaptcha.Client;
import com.DeathByCaptcha.SocketClient;
import com.DeathByCaptcha.HttpClient;
/* Put your DeathByCaptcha account username and password here.
Use HttpClient for HTTP API. */
Client client = (Client)new SocketClient(username, password);
try {
double balance = client.getBalance();
/* Put your CAPTCHA file name, or file object, or arbitrary input stream,
or an array of bytes, and optional solving timeout (in seconds) here: */
Captcha captcha = client.decode(captchaFileName, timeout);
if (null != captcha) {
/* The CAPTCHA was solved; captcha.id property holds its numeric ID,
and captcha.text holds its text. */
System.out.println("CAPTCHA " + captcha.id + " solved: " + captcha.text);
if (/* check if the CAPTCHA was incorrectly solved */) {
client.report(captcha);
}
}
} catch (AccessDeniedException e) {
/* Access to DBC API denied, check your credentials and/or balance */
}
答案 1 :(得分:1)
两个问题。
您的xpath错误,因此您获得NoSuchElement异常。
即使你有正确的xpath,你也无法提取文本,因为如果CAPTCHA
答案 2 :(得分:1)
CAPTCHA的全部目的是阻止UI的自动化!您可能希望使用内部API来验证操作。
答案 3 :(得分:1)
我有一个适用于特定网站的解决方案。您可以获取整个页面的快照并获取验证码的图像。然后将验证码图像的整个宽度除以总字符数(在验证码中通常它通常是不变的)。现在我们有了验证码图像的各个字符。通过重新加载页面来收集验证码的所有可能字符。
一旦你拥有了所有可能的角色,然后给出任何验证码图像,你可以将它的角色与我们拥有的图像进行比较,并决定它是哪个字母或数字。
要遵循的步骤:
收集验证码图像并将其划分为单个字符。
private static BufferedImage cropImage(File filePath, int x, int y, int w,
int h) {
try {
BufferedImage originalImgage = ImageIO.read(filePath);
BufferedImage subImgage = originalImgage.getSubimage(x, y, w, h);
return subImgage;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
现在读取验证码的每个字符图像,并将其与上述文件夹中的所有其他图像进行比较。 您可以使用像素值比较两个图像 public static float getDiff(File f1,File f2,int width,int height) 抛出IOException { BufferedImage bi1 = null; BufferedImage bi2 = null; bi1 = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB); bi2 = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
bi1 = ImageIO.read(f1);
bi2 = ImageIO.read(f2);
float diff = 0;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb1 = bi1.getRGB(i, j);
int rgb2 = bi2.getRGB(i, j);
int b1 = rgb1 & 0xff;
int g1 = (rgb1 & 0xff00) >> 8;
int r1 = (rgb1 & 0xff0000) >> 16;
int b2 = rgb2 & 0xff;
int g2 = (rgb2 & 0xff00) >> 8;
int r2 = (rgb2 & 0xff0000) >> 16;
diff += Math.abs(b1 - b2);
diff += Math.abs(g1 - g2);
diff += Math.abs(r1 - r2);
}
}
return diff;
}
在上面的图片中,图片名称指定数字或字符。
这仅适用于[ 1
等简单验证码答案 4 :(得分:1)
以下是从上图中读取文字的示例代码:
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.asprise.util.ocr.OCR;
public class ExtractImage {
WebDriver driver;
@BeforeTest
public void setUpDriver() {
driver = new FirefoxDriver();
}
@Test
public void start() throws IOException{
/*Navigate to http://www.mythoughts.co.in/2013/10/extract-and-verify-text-from-image.html page
* and get the image source attribute
*
*/
driver.get("http://www.mythoughts.co.in/2013/10/extract-and-verify-text-from-image.html");
String imageUrl=driver.findElement(By.xpath("//*[@id='post-body-5614451749129773593']/div[1]/div[1]/div/a/img")).getAttribute("src");
System.out.println("Image source path : \n"+ imageUrl);
URL url = new URL(imageUrl);
Image image = ImageIO.read(url);
String s = new OCR().recognizeCharacters((RenderedImage) image);
System.out.println("Text From Image : \n"+ s);
System.out.println("Length of total text : \n"+ s.length());
driver.quit();
/* Use below code If you want to read image location from your hard disk
*
BufferedImage image = ImageIO.read(new File("Image location"));
String imageText = new OCR().recognizeCharacters((RenderedImage) image);
System.out.println("Text From Image : \n"+ imageText);
System.out.println("Length of total text : \n"+ imageText.length());
*/
}
}
以下是上述程序的输出:
图片来源路径: http://2.bp.blogspot.com/-42SgMHAeF8U/Uk8QlYCoy-I/AAAAAAAADSA/TTAVAAgDhio/s1600/love.jpg
永远不要使用O,ne 谁喜欢你 永远不要说忙,一个人 谁需要你 永远不要欺骗The One 谁信任你, 永远不要吝啬一个人 谁Zways记住你。
总文字长度: 175
答案 5 :(得分:0)
忘记密码表单位于iframe中。这就是硒没有找到元素的原因。您需要先切换到保存表单的iframe,然后运行您的findelement。你的xpath是正确的。
使用driver.switchTo().frame(arg0)
切换到框架。请参阅javadoc here
要获取验证码文本,我不明白“存储测试和比较”的含义。理想情况下,您不应该从验证码中读取文本(正如其他人所提到的)。我看到的一种替代方法是将captcha值存储为alt text
在开发和QA环境中。这样您就可以阅读它并输入文本框。当代码进入生产环境或任何外部环境时,可以删除此alt text
。
答案 6 :(得分:0)
对于简单验证码,您可以拨打免费的ocr.space online OCR服务。只要这只是一个有点扭曲文本的图像就可以了。您也可以使用Google Cloud Vision OCR并且它同样有效,但设置起来有点复杂。
答案 7 :(得分:-2)
无法从CAPTCHA读取。如果您可以从CAPTCHA阅读,那么使用CAPTCHA是没有意义的。