智能协同云图库: 以图搜图(简单平替)
前言
现在视频教程里面的
以图搜图如果当到现在是不可用的,会报错{"status":1009,"msg":"system error","data":null},下面我将列出解决方法和新的替代方案。
百度以图搜图报错问题解决
-
进入到百度的以图搜图页面,并发送一个请求(建议使用
Firefox浏览器),打开F12; -
根据下图步骤找到对应的参数即可;
-
在
GetImagePageUrlApi类中的getImagePageUrl方法中,添加请求头即可解决;
▼java复制代码// 请求地址 String url = "https://graph.baidu.com/upload?uptime=" + uptime; String acsToken = "jmM4zyI8OUixvSuWh0sCy4xWbsttVMZb9qcRTmn6SuNWg0vCO7N0s6Lffec+IY5yuqHujHmCctF9BVCGYGH0H5SH/H3VPFUl4O4CP1jp8GoAzuslb8kkQQ4a21Tebge8yhviopaiK66K6hNKGPlWt78xyyJxTteFdXYLvoO6raqhz2yNv50vk4/41peIwba4lc0hzoxdHxo3OBerHP2rfHwLWdpjcI9xeu2nJlGPgKB42rYYVW50+AJ3tQEBEROlg/UNLNxY+6200B/s6Ryz+n7xUptHFHi4d8Vp8q7mJ26yms+44i8tyiFluaZAr66/+wW/KMzOhqhXCNgckoGPX1SSYwueWZtllIchRdsvCZQ8tFJymKDjCf3yI/Lw1oig9OKZCAEtiLTeKE9/CY+Crp8DHa8Tpvlk2/i825E3LuTF8EQfzjcGpVnR00Lb4/8A"; try { // 2. 发送 POST 请求到百度接口 HttpResponse response = HttpRequest.post(url) .form(formData) .header("Acs-Token", acsToken) .timeout(5000) .execute(); // 其他代码 } catch (Exception e) { log.error("搜索失败", e); throw new BusinessException(ErrorCode.OPERATION_ERROR, "搜索失败"); }
替换方案:使用360搜图代替,可以直接粘贴代码
1、我这里便于区分,对以图搜图这块的包进行的改造,如下图;
2、创建360搜图图片搜索结果类,SoImageSearchResult;
▼Java复制代码/** * 360搜图图片搜索结果 */ @Data public class SoImageSearchResult { /** * 图片地址 */ private String imgUrl; /** * 标题 */ private String title; /** * 图片key */ private String imgkey; /** * HTTP */ private String http; /** * HTTPS */ private String https; }
3、创建获取360搜图的图片的接口,GetSoImageUrlApi
说明:根据发送
360搜图的请求分析得知,360搜图会先把我们的图片上传到它的服务器中,然后根据这个图片的imgkey进行搜图;
▼Java复制代码/** * 获取360搜图的图片的接口 * * @author Baolong 2025年02月19 22:54 * @version 1.0 * @since 1.8 */ @Slf4j public class GetSoImageUrlApi { public static String getSoImageUrl(String imageUrl) { String url = "https://st.so.com/r?src=st&srcsp=home&img_url=" + imageUrl + "&submittype=imgurl"; try { Document document = Jsoup.connect(url).timeout(5000).get(); Element imgElement = document.selectFirst(".img_img"); if (imgElement != null) { String soImageUrl = ""; // 获取当前元素的属性 String style = imgElement.attr("style"); if (style.contains("background-image:url(")) { // 提取URL部分 int start = style.indexOf("url(") + 4; // 从"Url("之后开始 int end = style.indexOf(")", start); // 找到右括号的位置 if (start > 4 && end > start) { soImageUrl = style.substring(start, end); } } return soImageUrl; } throw new BusinessException(ErrorCode.OPERATION_ERROR, "搜图失败"); } catch (Exception e) { log.error("搜图失败", e); throw new BusinessException(ErrorCode.OPERATION_ERROR, "搜图失败"); } } public static void main(String[] args) { String imageUrl = "https://baolong-picture-1259638363.cos.ap-shanghai.myqcloud.com//public/10000000/2025-02-15_ILJxljPdt9Kv1EM1."; String result = getSoImageUrl(imageUrl); System.out.println("搜索成功,结果 URL:" + result); } }
3、创建获取360搜图搜索的图片的列表接口,GetSoImageListApi
▼Java复制代码/** * 获取360搜图搜索的图片的列表 * * @author Baolong 2025年02月19 22:58 * @version 1.0 * @since 1.8 */ @Slf4j public class GetSoImageListApi { /** * 获取图片列表 * * @param imageUrl 图片地址, 在 360 库中的地址 * @return 图片列表对象 */ public static List<SoImageSearchResult> getImageList(String imageUrl, Integer start) { String url = "https://st.so.com/stu?a=mrecomm&start=" + start; Map<String, Object> formData = new HashMap<>(); formData.put("img_url", imageUrl); HttpResponse response = HttpRequest.post(url) .form(formData) .timeout(5000) .execute(); // 判断响应状态 if (HttpStatus.HTTP_OK != response.getStatus()) { throw new BusinessException(ErrorCode.OPERATION_ERROR, "搜图失败"); } // 解析响应 JSONObject body = JSONUtil.parseObj(response.body()); // 处理响应结果 if (!Integer.valueOf(0).equals(body.getInt("errno"))) { throw new BusinessException(ErrorCode.OPERATION_ERROR, "搜图失败"); } JSONObject data = body.getJSONObject("data"); List<SoImageSearchResult> result = data.getBeanList("result", SoImageSearchResult.class); // 对结果进行处理, 因为返回的是分开的对象, 不是一个完整的图片路径, 这里需要自己拼接 for (SoImageSearchResult soImageSearchResult : result) { String prefix; if (StrUtil.isNotBlank(soImageSearchResult.getHttps())) { prefix = "https://" + soImageSearchResult.getHttps() + "/"; } else { prefix = "http://" + soImageSearchResult.getHttp() + "/"; } soImageSearchResult.setImgUrl(prefix + soImageSearchResult.getImgkey()); } return result; } public static void main(String[] args) { List<SoImageSearchResult> imageList = getImageList("http://p0.so.qhimg.com/t0257d29c212fceba5e.jpg", 0); System.out.println("搜索结果: " + JSONUtil.parse(imageList)); } }
4、创建360搜图图片搜索接口,SoImageSearchApiFacade
和鱼总一样也使用
门面模式,可以根据自行进行更改
▼Java复制代码/** * 360搜图图片搜索接口 * <p> * 这里用了 门面模式 */ @Slf4j public class SoImageSearchApiFacade { /** * 搜索图片 * * @param imageUrl 需要以图搜图的图片地址 * @param start 开始下表 * @return 图片搜索结果列表 */ public static List<SoImageSearchResult> searchImage(String imageUrl, Integer start) { String soImageUrl = GetSoImageUrlApi.getSoImageUrl(imageUrl); List<SoImageSearchResult> imageList = GetSoImageListApi.getImageList(soImageUrl, start); return imageList; } public static void main(String[] args) { // 测试以图搜图功能 String imageUrl = "https://baolong-picture-1259638363.cos.ap-shanghai.myqcloud.com//public/10000000/2025-02-15_lzn23PuxZqt8CPB1."; List<SoImageSearchResult> resultList = searchImage(imageUrl, 0); System.out.println("结果列表" + resultList); } }
5、新增接口searchPictureByPictureIsSo,或者在原来接口上修改即可
▼Java复制代码/** * 以图搜图 */ @PostMapping("/search/picture/so") public BaseResponse<List<SoImageSearchResult>> searchPictureByPictureIsSo(@RequestBody SearchPictureByPictureRequest searchPictureByPictureRequest) { ThrowUtils.throwIf(searchPictureByPictureRequest == null, ErrorCode.PARAMS_ERROR); Long pictureId = searchPictureByPictureRequest.getPictureId(); ThrowUtils.throwIf(pictureId == null || pictureId <= 0, ErrorCode.PARAMS_ERROR); Picture oldPicture = pictureService.getById(pictureId); ThrowUtils.throwIf(oldPicture == null, ErrorCode.NOT_FOUND_ERROR); List<SoImageSearchResult> resultList = new ArrayList<>(); // 这个 start 是控制查询多少页, 每页是 20 条 int start = 0; while (resultList.size() <= 50) { List<SoImageSearchResult> tempList = SoImageSearchApiFacade.searchImage( StrUtil.isNotBlank(oldPicture.getOriginUrl()) ? oldPicture.getOriginUrl() : oldPicture.getUrl(), start ); if (tempList.isEmpty()) { break; } resultList.addAll(tempList); start += tempList.size(); } return ResultUtils.success(resultList); }
6、前端修改
只需要把前端调用接口的地方修改一下即可,如果你是直接在百度搜图的基础上该的则不需要动前端; 但是需要把
SearchPicturePage页面展示的字段更换为imgUrl;
7、解决部分图片不显示
这里还是需要提一下,即使展示出来了图片,但是也有可能会有部分图片会展示不出来,可以根据自己的需要进行过滤即可。但是也有另外的方法解决,就是使用
referrer策略; 只需要在项目中的index.html文件中添加下方标签即可解决:
▼html复制代码<meta name="referrer" content="no-referrer">
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
学习完智能协同云图库项目后,想改造成springcloudalibaba架构的微服务项目,微服务划分如下:依赖服务:- 注册中心与配置中心: Nacos(负责服务注册发现以及各服务的动态配置管理)- 微服务网关(yunpic-backend-gateway): Gateway 聚合所有接口,统一接收处理前端请求,负责路由转发、鉴权与限流公共模块:- common 公共模块(yunpic-backe
4
云图库-以图搜图失效解决
7
个人博客
4
我在做云图库项目到部署上线阶段时,前后端已经成功部署到宝塔云上,我也能成功通过我的域名正常访问云图库,注册新账户也是注册成功且远程数据库也有信息,但是用已有的账号登录总是显示系统错误。我看了下我的redis密码正确且服务是正常运行请问有人遇到过同样的问题吗?
3
智能协同云图库-进入编辑报错解决
4
