这几年Python爬虫特别的火,我有个朋友是一个Python爬虫工程师,本人菜鸡Java开发工程师一名,最近所做的一个项目是需要去爬一个网页的数据,但是进入网页需要登录,登录需要输入图片验证码。爬虫的第三方jar包用的是jsoup,图片识别用的是tesj4j。话不多硕,上demo,奥利给!
一、下载jsoup.jar、tess4j的jar包,或者maven引入jsoup和tess4j的jar包。在windows环境下,但是tess4j本地开发需要调用dll文件还是需要的的,下载地址:点我。如下图一,是tess4j下载解压的完整目录,dist放的是tess4j的jar包,如果你用的是maven,就直接导入这个tess4j版本的jar,lib放的是windows执行的dll文件和开发中需要用的、依赖的jar包,tessdata是字库,我这里是纯识别数字,所以没有引入中文字库。我用的是maven,所以就只需要lib和tessdata这个两个文件夹。
二、获取验证码图片,识别图片中的验证码,设置用户名、密码,保持会话进行登录。
/**
*
* @param url 系统地址
* @param user 用户名
* @param pwd 密码
* @param tess4jpath tess4j的地址 如G:\test\Tess4J-3.4.8-src\Tess4J
* @return
*/
public Map login(String url, String user, String pwd,String tess4jpath) {
Map map = null;
Connection.Response LoginResponse = null;
try {
LoginResponse = Jsoup.connect(url).method(Connection.Method.GET).execute();
map = LoginResponse.cookies();//获取会话,登录后需要保持会话
Document document = LoginResponse.parse();
Element element = document.getElementById("验证码图片标签");
String codeimgurl = url+element.attr("src");
String codeimgpath = tess4jpath+"\\codeimg";
//下载验证码图片
byte[] codeimgdata = Jsoup.connect(codeimgurl).ignoreContentType(true).execute().bodyAsBytes();
FileUtils.saveImg(codeimgdata, codeimgpath, "codeimg.jpg");
//识别样本输出地址
String ocrResult = codeimgpath+"\\codetmpimgtmp.jpg";
String OriginalImg = codeimgpath+"\\codeimg.jpg";
//去噪点
FileUtils.removeBackground(OriginalImg, ocrResult);
ITesseract instance =new Tesseract();
instance.setDatapath(tess4jpath);
File imgDir =new File(ocrResult);
String code = instance.doOCR(imgDir);//识别验证码
System.out.println("code:"+code);
Map datas = new HashMap();
datas.put("user", user);
datas.put("pwd", pwd);
datas.put("ident",code);
Connection connection = Jsoup.connect(url+"/login?op=userLogin");
//输入用户名和密码保持会话登录
Connection.Response response1 = connection.data(datas).cookies(map).method(Connection.Method.POST).execute();
} catch (IOException e) {
map = null;
e.printStackTrace();
} catch (TesseractException e) {
map = null;
e.printStackTrace();
}finally {
return map;
}
}
上述代码中使用的工具类
public class FileUtils {
/**
* 级联创建目录
* @param path
*/
public static void creatDir(String path) {
File file = new File(path);
if(!file.exists()) {
file.mkdirs();
}
}
/**
* 验证码图片处理
* @param imgUrl
* @param resUrl
*/
public static void removeBackground(String imgUrl, String resUrl){
//定义一个临界阈值
int threshold = 300;
try{
BufferedImage img = ImageIO.read(new File(imgUrl));
int width = img.getWidth();
int height = img.getHeight();
for(int i = 1;i < width;i++){
for (int x = 0; x < width; x++){
for (int y = 0; y < height; y++){
Color color = new Color(img.getRGB(x, y));
//System.out.println("red:"+color.getRed()+" | green:"+color.getGreen()+" | blue:"+color.getBlue());
int num = color.getRed()+color.getGreen()+color.getBlue();
if(num >= threshold){
img.setRGB(x, y, Color.WHITE.getRGB());
}
}
}
}
for(int i = 1;i
注意:并不是所有的系统的验证码都能识别,就拿这个12306来说,我也不知道怎么识别,关键是我也不敢问啊!我识别的验证码是简单的数字验证码,原始验证码 ,去噪的验证码
,去噪后的验证码便于识别数字。
不管怎么样,希望你使用的Java爬虫要用在正途上,毕竟最近也听说了有爬虫工程师被抓判刑的消息,所谓细水长流,我们要走可持续发展的道路。