基于JAVA解决淘宝爬虫限制

版权声明:柠檬乐园:200145783 https://blog.csdn.net/u014431237/article/details/83791659

前言

以前做过淘客开发,那时候高佣api很少,高佣的办法就是查询商品模拟转链为高佣,但是后来淘宝慢慢禁止了爬虫一直弹验证码,后来我就利用验证码识别成功扛过那段日子,大批淘宝工具商发布高佣接口,验证码识别也就没有用了。本文说的并不是指怎么利用图像去识别的技术,而是怎么突破淘宝的接口限制让爬虫可以获取信息。

验证码识别

你可以去各大验证码的打码平台识别或者自己写识别库。
以后如果我有时间可能会搭建一下验证码识别的接口~再说吧

工具

Google浏览器,Fiddler代理工具,IDEA(代码编写),验证码识别接口。

分析

  1. 当去模拟请求一个淘宝页面的时候,如果过于频繁会302转向到类似如下界面
    在这里插入图片描述
  2. 分析一下提交的参数
    在这里插入图片描述
    可以看到checkcode 就是我们输入的数字,如果输入对了就会跳转到原url,否则将会继续请求验证码图片url,
    在这里插入图片描述在这里插入图片描述
    关于其他参数和验证码图片的url都可以在这个验证HTM文本中找到。除了提交的checkcode(验证码)的需要自己输入,还有淘宝ua的算法比较难搞其他的参数本来在页面就是有的,经测试ua其实对验证码提交无影响,所以只需要识别验证码就可以啦。
  3. 输入正确的验证码就可以继续访问的原来的接口

编码

Java HTTP请求模块,个人最喜欢的~当然你也可以用httpckient等其他模块。

Requests is a http request lib with fluent api for java, inspired by the python request module. Requests requires JDK 1.7+.
https://github.com/hsiafan/requests

		//首先访问原始接口
            resp = Requests.get(url2).headers(headersmap).send();
            result1 = resp.readToText();
            //如果获取的原始接口中内容为空 就表示淘宝限制了
            String createtime = getMiddleText.......//省略
            
            //仅仅识别五次,五次还不通过,就放弃本条数据
            for (int i = 0; i < 5 && StringUtils.isEmpty(createtime); i++) {
            	//获取验证码图片url
                String codeurl = "https:" + getMiddleText(result1, "<img id=\"checkcodeImg\" src=\"", "\"");
                //调用识别接口
                String code = getCode(codeurl);
                System.out.println("这是识别后的结果" + code);
                //获取页面其他参数
                Map<String, Object> map = getParamsMap(result1, code);
                //模拟手动输入验证码  提交数据(这个函数 我在下面会公开,因为涉及到一些坑)
                String coderes = queryCode(map, headersmap);
                createtime = getMiddleText(coderes, ....//省略
            }

拼接参数函数
这里说明一下,requests提交的时候默认会自动编码成utf8

  public static Map getParamsMap(String text, String code) {
        text = text.replaceAll("amp;", "");
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            Pattern pattern = Pattern.compile("<input type=\"hidden\" name=\"(.*?)\" value=\"(.*?)\"");
            Matcher matcher = pattern.matcher(text);
            //正则批量提取form中参数
            while (matcher.find()) {
               //URLEncoder.encode(matcher.group(2), "utf-8");
                map.put(matcher.group(1), matcher.group(2)); 
            }
            //识别的验证码
            map.put("checkcode", code);
            //无影响
            map.put("ua", "");

            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

提交验证码参数,注意一定要用淘宝cookie。

 /*验证码识别--提交识别结果*/
    public static String queryCode(Map<String, Object> map, Map headersMap) {
        RawResponse rawResponse = Requests.post("https://sec.taobao.com/query.htm").body(map)
               .headers(headersMap)
                .send();
           //代理模式 我一般是调试的时候结合Fiddler,这样就可以在Fiddler看到java请求,很方便找出模拟和实际的区别     
        // .proxy(Proxies.httpProxy("127.0.0.1", 8888))
        //打印响应头
         System.out.println(rawResponse.getHeaders().toString());
        String code = rawResponse.readToText();
        return code;
    }

数据演示

可以发现一般都是识别一次就可以获取到数据了,并不用识别5次,(当然这个更识别准确度有关~~~)
在这里插入图片描述

后记

使用resquests模块居然发现他默认编码utf8,导致我一直error。后来通过Http代理到FIddler查看请求才发现(Fiddler直接是抓不到调试的时候http数据包,所以只有手动代理才能发现)
提交验证码的时候需要淘宝cookie,不然返回过去也有问题
Java的正则写多行的话是真的难看啊~~~一堆的\n什么的 以后也不方便修改~
另外关于验证是滑块的也可以通过打码来解决的~我没去深究,有兴趣的可以自己尝试……

猜你喜欢

转载自blog.csdn.net/u014431237/article/details/83791659