最近做爬虫时碰到了521错误,500开头的都是服务器错误;521错误码需要请求多次才能返回正确的结果;查看请求次数需要借助抓包工具,我自己使用Fiddler 4抓取到发送了三次请求才拿到结果,所以这就需要我们解析三次请求了。

1、Fiddler 抓取结果两次521、1次200拿到了结果,这就意味着我们需要提交三次请求才能拿到结果。

2、根据抓包看到必须三次请求才能拿到结果,我们逐一解析每次请求和响应。下面是正确拿到结果的请求头,红框内的cookie是重点。

1)、我们使用postman发送第一次请求,得到响应头Set-Cookie中的

__jsluid_s=ed2b28b0b03114218d2b0e03a1b56f12,此参数在第二次,第三次请求时加入cookie中(两次请求中此参数值保持不变);还有另一个参数就是返回值js代码(返回值中的js也可以在html中打印出来),使用ScriptEngineManager处理两个红竖杠中的js;得到__jsl_clearance_s=1628664214.493|-1|cx9ymjyfz6PzeXeREg6KcTa7P24%3D;(它后面的代码不需要)

2)、将__jsluid_s和__jsl_clearance_s放入到cookie中再次发送请求,会得到返回值是一大串js代码,跟第一次的返回值不一样,这个又多又乱,看到下图中的代码眼晕吧

别慌,咱们看重点,将返回值拉到最后,两个红竖杠之间才是我们想要的,所以上面那么一大堆代码我们可以不用管它;直接看重点,仔细看看这段是不是有点眼熟,这就是解密的关键。

首先我们看bts对象,是不是很像__jsl_clearance_s参数值,没错,这就是第三次请求的cookies参数的部分值(是一大部分),chars,ct,ha这几个对象是解密的关键,chars是随机的字母,ha是加密算法(MD5,sha1,sha256三种算法),ct是加密的结果,看到这,各位应该想到了解析方式;我们可以对比标准的数据__jsl_clearance_s=1628662388.812|0|nzqTL5FJzLGZp%2BuNyQfckpBkghQ%3D

__jsl_clearance_s = (bts数组1)+(chars随机两个字母)+(bts数组2),

这就是第二个参数值

3)、根据第一次得到的不变参数__jsluid_s与第二次得到的__jsl_clearance_s在次发送请求,就能拿到结果了。

3、最后,我将我自己的代码贴上来,供大家参考;提醒:在第二次请求解析__jsl_clearance_s参数的方式不一定能使用到什么时候,如果过段时间他们更新了其他加密方法,就需要各位自行处理了。

============================

/*** cookie参数*/
private static String JSL_UID = "";/*** cookie参数*/
private static String JSL_CLEARANCE = "";
/**
* @Description 抓取网上的图片
* @Author  lqt
* @Date   2021/8/4
* @Param imgSrc 图片路径
* @Param www 域名地址
* @Return
* @Exception
*/
public static void downloadImgByNet(String imgSrc,String www) {CloseableHttpClient client = null;​​​​​​​CloseableHttpResponse response = null;try {//设置https协议访问System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2,SSLv3");// 发送请求client = HttpClients.createDefault();RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(TIME_OUT).setSocketTimeout(TIME_OUT).setConnectTimeout(TIME_OUT).build();HttpGet get = new HttpGet(imgSrc);get.setConfig(requestConfig);//模拟浏览器get.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");get.setHeader("Accept-Encoding", "gzip, deflate, br");get.setHeader("Accept-Language", "zh-CN,zh;q=0.9");get.setHeader("Cache-Control", "no-cache");get.setHeader("Connection", "keep-alive");get.setHeader("Host", www);get.setHeader("Cookie", JSL_UID + ";" + JSL_CLEARANCE);get.setHeader("Pragma", "no-cache");get.setHeader("sec-ch-ua", "Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91");get.setHeader("sec-ch-ua-mobile", "?0");get.setHeader("Sec-Fetch-Dest", "document");get.setHeader("Sec-Fetch-Mode", "navigate");get.setHeader("Sec-Fetch-Site", "none");get.setHeader("Sec-Fetch-User", "?1");get.setHeader("Upgrade-Insecure-Requests", "1");get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36");response = client.execute(get);// 第一次请求响应头中的,在第二次第三次请求需要带此参数String jsluid_s = "";// 第二次请求 带入 __jsluid_s 与 __jsl_clearance_sif (response.getStatusLine().getStatusCode() == HTTP_521) {System.out.println("错误-521");Header[] hs = response.getHeaders("Set-Cookie");if(Objects.isNull(hs) || hs.length < 1){System.out.println("获取Set-Cookie错误");downloadImgByNet(imgSrc,filePath,fileName,www,"");}jsluid_s = "__jsluid_s=" + hs[0].toString().split(";")[0].split("=")[1];HttpEntity entity = response.getEntity();String resHtml = EntityUtils.toString(entity);// 对返回js处理 拿到jsl_clearanceString jsl_clearance_s = getJslClearance(resHtml);get.setHeader("Cookie", jsluid_s + ";" + jsl_clearance_s);response = client.execute(get);}// 第三次请求 带入 __jsluid_s 与 __jsl_clearance_s(重新计算得到的与第二次不同)if (response.getStatusLine().getStatusCode() == HTTP_521) {HttpEntity entity = response.getEntity();String resHtml = EntityUtils.toString(entity);// 对返回js处理 拿到jsl_clearanceresHtml = resHtml.substring(resHtml.lastIndexOf("go(") + 3, resHtml.lastIndexOf(")"));JSONObject data = JSON.parseObject(resHtml);String jsl_clearance_s = go(data);JSL_UID = jsluid_s;JSL_CLEARANCE = jsl_clearance_s;get.setHeader("Cookie", jsluid_s + ";" + jsl_clearance_s);response = client.execute(get);}// 输出文件if (response.getStatusLine().getStatusCode() == HttpStatus.HTTP_OK) {//拿到最终想要的页面HttpEntity entity = response.getEntity();if(!Objects.isNull(entity)){String s = IOUtils.toString(entity.getContent(), StandardCharsets.UTF_8);}}}catch (Exception e){e.printStackTrace();}finally {try {if(response != null) {response.close();}} catch (IOException e) {e.printStackTrace();}}
}
/**
* @Description 将第一次返回js数据转换
* @Author  lqt
* @Date   2021/8/3
* @Param body js文件
* @Return
* @Exception
*/
private static String getJslClearance(String body){String jsl_clearance = "";ScriptEngineManager manager = new ScriptEngineManager();//得到脚本引擎ScriptEngine engine = manager.getEngineByName("JavaScript");//处理加密jsString js = body.trim().replace("<script>", "").replace("</script>", "").replace("document.cookie=", "").replace("location.href=location.pathname+location.search", "");try {//得到解密后的jsString result = (String) engine.eval(js);jsl_clearance = result.split(";")[0];} catch (ScriptException e) {e.printStackTrace();}return jsl_clearance;
}/**
* @Description 处理第二次返回js数据
* @Author  lqt
* @Date   2021/8/3
* @Param data go对象
* @Return
* @Exception
*/
private static String go(JSONObject data) {String[] bts = data.getObject("bts",String[].class);String ct = data.getString("ct");String[] chars = data.getString("chars").split("");String ha = data.getString("ha");for (int i = 0; i < chars.length; i ++){for (int j = 0; j < chars.length; j ++){String i1 = chars[i];String j1 = chars[j];String cookie = bts[0] + i1 + j1 + bts[1];if (Objects.equals(hash(cookie,ha),ct)) {return "__jsl_clearance_s=" + cookie;}}}return "";
}
/**
* @Description 匹配加密  sha1,sha256,md5
* @Author  lqt
* @Date   2021/8/3
* @Param  cookie需要加密的字符串
* @Param ha 加密类型
* @Return
* @Exception
*/
private static String hash(String cookie, String ha){String str = "";try {switch (ha){case "sha1":str = HeaUtil.sha1(cookie);break;case "sha256":str = HeaUtil.sha256(cookie);break;case "md5":str = HeaUtil.md5(cookie);break;default:break;}return str;}catch (Exception e){e.printStackTrace();}return str;
}

============== 下面代码为工具类

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;/**
* @Description HeaUtil
* Hash encryption algorithm
* 哈希加密算法:MD5、SHA-1、SHA-256、HMAC-SHA-1、HMAC-SHA-256
* 需要导入 org.apache.commons.codec 包
* @Author  lqt
* @Date   2021/8/3
* @Param
* @Return
* @Exception
*/
@SuppressWarnings("WeakerAccess")
public class HeaUtil {/*** md5加密** @param text 内容* @return digest 摘要* @throws NoSuchAlgorithmException e*/public static String md5(String text) throws NoSuchAlgorithmException {MessageDigest messageDigest = MessageDigest.getInstance("MD5");byte[] bytes = messageDigest.digest(text.getBytes());return Hex.encodeHexString(bytes);}/*** sha1加密** @param text 内容* @return digest 摘要* @throws NoSuchAlgorithmException e*/public static String sha1(String text) throws NoSuchAlgorithmException {MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");byte[] bytes = messageDigest.digest(text.getBytes());return Hex.encodeHexString(bytes);}/*** sha256加密** @param text 内容* @return digest 摘要* @throws NoSuchAlgorithmException e*/public static String sha256(String text) throws NoSuchAlgorithmException {MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");byte[] bytes = messageDigest.digest(text.getBytes());return Hex.encodeHexString(bytes);}/*** hmac-sha1加密** @param text 内容* @param key 密钥** @return 密文* @throws Exception e*/public static String hmacSha1(String text, String key) throws Exception {SecretKeySpec sk = new SecretKeySpec(key.getBytes(), "HmacSHA1");return hmacSha1(text, sk);}/*** hmac-sha1加密** @param text 内容* @param sk 密钥** @return 密文* @throws Exception e*/public static String hmacSha1(String text, SecretKeySpec sk) throws Exception {Mac mac = Mac.getInstance("HmacSHA1");mac.init(sk);byte[] rawHmac = mac.doFinal(text.getBytes());return new String(Base64.encodeBase64(rawHmac));}/*** 生成 HmacSha1 密钥** @param key 密钥字符串* @return SecretKeySpec*/public static SecretKeySpec createHmacSha1Key(String key) {return new SecretKeySpec(key.getBytes(), "HmacSHA1");}/*** hmac-sha256加密** @param text 内容* @param key 密钥** @return 密文* @throws Exception e*/public static String hmacSha256(String text, String key) throws Exception {SecretKeySpec sk = new SecretKeySpec(key.getBytes(), "HmacSHA256");return hmacSha1(text, sk);}/*** hmac-sha256加密** @param text 内容* @param sk 密钥** @return 密文* @throws Exception e*/public static String hmacSha256(String text, SecretKeySpec sk) throws Exception {Mac mac = Mac.getInstance("HmacSHA256");mac.init(sk);byte[] rawHmac = mac.doFinal(text.getBytes());return new String(Base64.encodeBase64(rawHmac));}/*** 生成 HmacSha256 密钥** @param key 密钥字符串* @return SecretKeySpec*/public static SecretKeySpec createHmacSha256Key(String key) {return new SecretKeySpec(key.getBytes(), "HmacSHA256");}/*** 测试** @param args args*/public static void main(String[] args) throws Exception {String s = "123456789了踩踩踩";System.out.println(md5(s));System.out.println(sha1(s));System.out.println(sha256(s));String k = "ada232@12";System.out.println(hmacSha1(s, k));s = "aeqnfoavneornqoenr1啊可是到了南方情况无法弄清了我呢010jownfasdfqijqor";System.out.println(hmacSha1(s, k));SecretKeySpec sk1 = createHmacSha1Key(k);System.out.println(hmacSha1(s, sk1));SecretKeySpec sk256 = createHmacSha256Key(k);System.out.println(hmacSha256(s, sk256));}
}

java 爬虫 抓取网上的图片报错521解决方案相关推荐

  1. Java爬虫抓取网页

    Java爬虫抓取网页 原作者:hebedich  原文链接 下面直接贴代码: import java.io.BufferedReader; import java.io.InputStreamRead ...

  2. java爬虫抓取网页数据论坛_Java爬虫抓取网页

    Java爬虫抓取网页原作者:hebedich  原文链接 下面直接贴代码: import java.io.BufferedReader; import java.io.InputStreamReade ...

  3. Java爬虫爬取wallhaven的图片

    Java爬虫爬取wallhaven的图片 参考文章:JAVA Jsoup爬取网页图片下载到本地 需要的jar包:jsuop wallhaven网站拒绝java程序访问,所以要伪装报头. 发送请求时 C ...

  4. java爬虫 抓取知乎,java爬虫抓取知乎推荐总是乱码

    求助java爬虫抓取知乎推荐总是乱码 仿照http://blog.csdn.net/pleasecallmewhy/article/details/17630063写一个简单的抓取知乎推荐(http: ...

  5. Java爬虫抓取豆瓣读书信息

    要求: Java爬虫抓取豆瓣读书信息中关于"编程,算法,互联网"评分最高的前100本书(要求评论数量大于1000) 实现思路: 1.通过手动打开豆瓣读书的主页面 https://b ...

  6. 2011年1月13日抓取的QQ空间报错信息

    这是2011年1月13日抓取的QQ空间报错信息,当时是QQ空间里的"Q宠大乐斗"插件升级,一直报503错误,持续了大概半小时. 在此抓图以作留念.

  7. Java爬虫抓取网页数据(抓取慕课网论坛为实例)

    1. 网络爬虫 网络爬虫(英语:web crawler),也叫网络蜘蛛(spider),是一种用来自动浏览万维网的网络机器人.其目的一般为编纂网络索引.简单来说,就是获取请求的页面源码,再通过正则表达 ...

  8. Python 爬虫: 抓取花瓣网图片

    接触Python也好长时间了,一直没什么机会使用,没有机会那就自己创造机会!呐,就先从爬虫开始吧,抓点美女图片下来. 废话不多说了,讲讲我是怎么做的. 1. 分析网站 想要下载图片,只要知道图片的地址 ...

  9. Python爬虫抓取指定网页图片代码实例

    更多编程教程请到:菜鸟教程 https://www.piaodoo.com/ 友情链接:好看站 http://www.nrso.net/ 高州阳光论坛https://www.hnthzk.com/ 想 ...

最新文章

  1. 获得虚拟服务器相对路径,在web应用中获取相对路径和绝对路径
  2. mysql数据库保存中文乱码解决参考方案
  3. python 安装scrapy,openssl opensslv.h错误的解决办法
  4. 计算机网络实训简介,计算机网络实验报告介绍.doc
  5. 项目经理应如何调动员工的积极性
  6. 内存或磁盘空间不足 excel无法再次打开_Mac系统中检测和清理磁盘空间的几个工具...
  7. 软件测试常见面试题目(1)pareto法则,帕累托法则,28杀虫剂怪事,木桶原理,Good-enough原则群集效应,测试与调试的区别,QA以及职责,测试工程师和软件质量保证的,测试提交的缺陷开发人员
  8. SpringbootJPA分页 PageRequest过时
  9. SpringAOP:连接点和切点的区别
  10. php在线电子小说网站毕业设计源码
  11. Mozilla5.0的意思
  12. html 滑动刻度尺,js实现移动端H5页面手指滑动刻度尺功能
  13. vostro3470装win7_dell latitude3470怎么安装win7系统
  14. 《linux内核分析》第三次课 实验作业
  15. 『数据分析』使用python进行同期群分析
  16. opencv android 透视,Opencv for Android 之透视变换
  17. Java获取时间格式(年月日时分秒毫秒)
  18. 简易教程:教你如何使用Meshlab提取已有的三维模型的结构点云
  19. C语言在中math.h中sqrt()函数的使用
  20. 转:德鲁克:什么决定了你的未来

热门文章

  1. 机器学习[k近邻算法]
  2. JMX远程监视Java进程
  3. 成年人应该如何学习?教你摆脱知识焦虑
  4. Python之计数器 (Counter)
  5. 梯度下降详解(3)机器学习
  6. 2021数据通信技术-初级工程师-认证题库
  7. 亚人中的中村慎也事件—中村慎也剧场版提前一览
  8. Springboot+vue项目二手交易平台系统
  9. vue绑定键盘事件无效问题,vue绑定键盘delete事件示例,组合键绑定
  10. 洛谷 P3205 [HNOI2010]合唱队 解题报告