用Python蹭别人家图片接口,做一个【免费图床】吧

news2025/7/15 17:31:29

打开本文,相信你确实需要一个免费且稳定的图床,这篇博客就让你实现。

文章目录

    • ⛳️ 谁家的图床
    • ⛳️ 实战编码
    • ⛳️ 第一轮编码
    • ⛳️ 第二轮编码
    • ⛳️ 第三轮编码
    • ⛳️ 第四轮编码

⛳️ 谁家的图床

这次咱们用新浪微博来实现【免费图床应用】,通过代码实现图片上传,然后再进行移花接木,获取图片可读地址。

正式编码前,先做一下准备工作。

  1. 注册一个微博账号,或者用自己旧的也行;
  2. 安装 Python 环境;
  3. 安装 requests 模块。

上述后两步,作为一个合格的 Python 程序员,相信对你来说没有任何难度。

本案例不做自动化微博登录,直接获取 Cookie 信息。

⛳️ 实战编码

首先通过操作微博各个终端界面,找到最简单的图片上传接口和对应参数。

在切换到苹果设备访问时,得到如下界面,发现一个精选图片上传按钮。

在这里插入图片描述

点击按钮之后,任选一张图片,得到如下接口信息。

接口地址:https://m.weibo.cn/api/statuses/uploadPic
参数表如下(关键信息自行获取即可,博客中进行打码操作):

  • type: json
  • pic: (二进制)
  • st: 参数值位置
    _spr: screen:390x844

其中 pic 是图片的二进制编码,一会实战的时候,我们可以对参数表进行删项测试,查看哪些为必填参数。

用户上传图片时,还必须携带 cookie 值,这个通过开发者工具获取即可。

⛳️ 第一轮编码

既然知道请求接口和参数了,那直接使用 requests 模块,模拟用户上传操作,查看一下效果。

import requests


def upload_img():
    headers = {
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
        "Cookie": "请自行复制登录之后的 Cookie"
    }

    data = {
        'type': 'json',
        'st': 'e940df',
        '_spr': 'screen:390x844',
        'pic': open('./test_img.png', 'rb')
    }

    res = requests.post('https://m.weibo.cn/api/statuses/uploadPic',
                        data=data, headers=headers)
    print(res.text)


if __name__ == '__main__':
    upload_img()

本想着一次性就成功,结果得到如下信息。

{"ok":0,"errno":"100015","msg":"\u4e0d\u5408\u6cd5\u7684\u8bf7\u6c42"}

将 unicode 编码的 msg 参数转码之后,错误提示为 不合法的请求。看来没有想象中那么容易完成。

既然是请求非法,那一定是在请求头中加入了识别标记,查看请求头信息,发现如下参数。

在这里插入图片描述

⛳️ 第二轮编码

在请求头中出现了 token 值,非常典型的加密参数,而且这个参数和代码请求中传递的 st 参数一致。那继续修改代码,在请求头中加入该参数。

import requests


def upload_img():
    headers = {
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
        "Cookie": "请自行复制登录之后的 Cookie"

    }
    st = 'e940df'
    headers["x-xsrf-token"] = st

    data = {
        'type': 'json',
        'st': st,
        '_spr': 'screen:390x844',
        'pic': open('./test_img.png', 'rb')
    }

    res = requests.post('https://m.weibo.cn/api/statuses/uploadPic',
                        data=data, headers=headers)
    print(res.text)

结果得到的信息依旧是请求非法,那继续在请求头中增加参数。当补齐之后,发现得到的错误信息变了,具体如下所示。

 headers = {
        "accept": "application/json, text/plain, */*",
        "origin": "https://m.weibo.cn",
        "referer": "https://m.weibo.cn/",
        "mweibo-pwa": "1",
        "x-requested-with": "XMLHttpRequest",
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
        "Cookie": "请自行复制登录之后的 Cookie"
    }

新的错误信息依旧是请求非法。

{"ok":0,"errno":"100006","msg":"\u8bf7\u6c42\u975e\u6cd5"}

⛳️ 第三轮编码

那既然增加 x-xsrf-token 还是无法得到数据,那只能多次测试上传,查看该参数变化。

再次测试之后,发现该值会动态获取,调用的接口信息如下所示。

请求地址:https://m.weibo.cn/api/config
无请求参数,微博默认是间隔一段时间自动修改该值,这里我们修改为手动触发,新版代码如下所示。

import requests


def upload_img():
    headers = {
        "accept": "application/json, text/plain, */*",
        "origin": "https://m.weibo.cn",
        "referer": "https://m.weibo.cn/",
        "mweibo-pwa": "1",
        "x-requested-with": "XMLHttpRequest",
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
        "Cookie": "请自行复制登录之后的 Cookie"

    }
    res = requests.get('https://m.weibo.cn/api/config', headers=headers)
    st = res.json()['data']['st']
    print(st)
    headers["x-xsrf-token"] = st
    data = {
        'type': 'json',
        'st': st,
        '_spr': 'screen:390x844'
    }

    data = {
        'type': 'json',
        'st': st,
        '_spr': 'screen:390x844',
        'pic': open('./test_img.png', 'rb')
    }

    res = requests.post('https://m.weibo.cn/api/statuses/uploadPic',
                        data=data, headers=headers)
    print(res.text)


if __name__ == '__main__':
    upload_img()

结果没有错误码了,又出现新的提示信息了。

{"ok":0,"msg":"\u4e0a\u4f20\u5931\u8d25\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5"}

转义之后,最新的提示是上传失败,请稍后重试,看来已经接近成功了,下面的代码实现是多年爬虫编码经验实现的。

既然接口提示的仅仅是上传失败,那再次回到开发者工具中查看,通过载荷卡片,可以看到是上传的表单数据,那我们使用 data 参数是完全没有问题的,但是切换到源代码视图就会发现问题。下面是两张对比图。

在这里插入图片描述
在这里插入图片描述

⛳️ 第四轮编码

在源代码视图中发现微博的该接口是使用的 multipart/from-data 类型数据,在 Python 中有两种方式来实现,分别如下。

  • 手动创建 form-data 并通过 headers 传递;
  • 通过 files 参数传递。

那咱们采用第二种实现,在 requests 的官方手册中也是推荐该方式,使用 requests 模拟一个表单的数据格式,语法如下。

files = {{name}: (<filename>, <file object>,<content type>, <per-part headers>)}

该行代码模拟出来的 POST 数据格式恰好和刚才的图片格式一致。

Content-Disposition: form-data; name={name};filename=<filename>
Content-Type: <content type>

<file object>
--boundary

其中各参数留空,使用 None 进行占位。

所以本案例中请求参数修改为如下格式。

file = {
        'pic': ('test_img.png', open('./test_img.png', 'rb'), 'image/png'),
        'type': (None, 'json'),
        'st': (None, st),
        '_spr': (None, 'screen:390x844')
    }

同时在 requests 模块调用 POST 方法的时候,使用 files 参数,完整代码如下所示。

import requests


def upload_img():
    headers = {
        "accept": "application/json, text/plain, */*",
        "origin": "https://m.weibo.cn",
        "referer": "https://m.weibo.cn/",
        "mweibo-pwa": "1",
        "x-requested-with": "XMLHttpRequest",
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
        "Cookie": "请自行复制登录之后的 Cookie"

    }
    res = requests.get('https://m.weibo.cn/api/config', headers=headers)
    st = res.json()['data']['st']
    print(st)
    headers["x-xsrf-token"] = st
    data = {
        'type': 'json',
        'st': st,
        '_spr': 'screen:390x844'
    }

    # data = {
    #     'type': 'json',
    #     'st': st,
    #     '_spr': 'screen:390x844',
    #     'pic': open('./test_img.png', 'rb')
    # }
    file = {
        'pic': ('test_img.png', open('./test_img.png', 'rb'), 'image/png'),
        'type': (None, 'json'),
        'st': (None, st),
        '_spr': (None, 'screen:390x844')
    }
    res = requests.post('https://m.weibo.cn/api/statuses/uploadPic',
                        files=file, headers=headers)
    print(res.text)


if __name__ == '__main__':
    upload_img()

运行代码,得到最终结果,响应数据如下所示。

{"pic_id":"xxxxxx","thumbnail_pic":"xxxxxxx","bmiddle_pic":"xxxxxxx","original_pic":"xxxxxx"}

但是这个图床案例还没有完结,你得到的图片地址,如果直接使用浏览器访问,会被禁止(403 Forbidden),即限制了外链调用。

使用下述代码进行修复,即可外联访问。

pic_id = res.json()["pic_id"]
# 拼接图片地址
img = 'http://ww1.sinaimg.cn/large/{pid}.jpg'.format(pid=pic_id)
print(img)

不要问我,为什么 ww1 就可以访问到图片,这是前贤们探究出来的。

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 621 篇原创博客

从订购之日起,案例 5 年内保证更新

  • ⭐️ Python 爬虫 120,点击订购 ⭐️
  • ⭐️ 爬虫 100 例教程,点击订购 ⭐️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

栈浅谈(上)

目录 栈的定义 栈的实现 初始化 判断栈是否为空 入栈操作 获取栈顶元素 出栈操作 遍历栈 销毁栈 完整代码演示 栈—STL 基本操作 例题 参考代码 栈的定义 说到栈&#xff0c;一些不会计算机语言的“小白”&#xff08;我就是&#xff09;就会想到栈道之类的词语…

基于JavaWeb的婚恋交友网站设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

如何平衡新老策略的好与坏,一道常见风控送命题解答

作为一个风控策略从业者&#xff0c;在做风险管理的过程中一直在做的就是&#xff0c;不断的挖掘有效的变量特征来填充风控决策体系&#xff0c;使决策体系的功效变大变强&#xff0c;最终形成一套可变的稳定风险护盾。我们常见的一个场景比如如何筛选一些新策略来挑战老策略&a…

【C++中预处理语句 include、define、if】

1.预处理阶段 预处理阶段&#xff0c;在实际发生编译之前就根据对应的预处理语句进行操作&#xff0c;等到预处理阶段完成之后才进行编译阶段 。 2.预处理语句 预处理语句主要有include、define、if 和 program。利用 # 进行标记 2.1 include语句 include语句就是将所包含的…

if-else练习

if单分支 输入两个数&#xff0c;分别放入x和y中&#xff0c;若两数不相等&#xff0c;则输出其中的大数&#xff0c;若两数相等&#xff0c;则输出字符串“xy&#xff1a;”并输出其值 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() {int a 0;int …

智慧油田解决方案-最新全套文件

智慧油田解决方案-最新全套文件一、建设背景1、智慧油田的概念及意义2、智慧油田的建设目标二、建设思路三、建设方案四、获取 - 智慧油田全套最新解决方案合集一、建设背景 1、智慧油田的概念及意义 石油产量、采收率、安全生产等都与石油工业未来息息相关&#xff0c;随着石…

十八、CANdelaStudio深入-Data Types

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio的Data Types(数据类型),欢迎各位朋友订…

旧系统改造

背景 很多时候&#xff0c;我们在项目前期会优先确保项目业务的落地&#xff0c;在短时间内进行项目冲刺&#xff0c;最后完成项目上线。这样做让短时间内的目标达貌似达成了&#xff0c;却给系统留下了很大的隐患。 在项目的冲刺过程中&#xff0c;我们的精力大部分花在了业…

动态规划-不同路径

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; 示例 …

单源广度优先搜索 (leetcode经典例题 C++实现)

文章目录01矩阵地图分析腐烂的橘子深度优先搜索与广度优先搜索前情回顾&#xff1a; 深度搜索dfs与广度搜索bfs算法总结&#xff08;c 例题&#xff09; 本节是广度优先搜索的进阶&#xff1a; 01矩阵 传送门&#xff1a; https://leetcode.cn/problems/01-matrix/?envType…

JavaWeb----Servlet技术

JavaEE简介 什么是JavaEE JavaEE&#xff08;Java Enterprise Edition&#xff09;&#xff0c;Java企业版&#xff0c;是一个用于企业 级web开发平台,它是一组Specification。最早由Sun公司定制并发 布&#xff0c;后由Oracle负责维护。在JavaEE平台规范了在开发企业级web 应…

【操作系统】死锁(详细)

文章目录一、死锁的概念二、死锁的产生因素三、死锁的必要条件1、互斥条件2、占有和等待条件&#xff08;部分分配条件&#xff09;3、不剥夺条件4、循环等待条件&#xff08;环路条件&#xff09;四、死锁防止1、破坏互斥条件2、破坏占有和等待条件3、破坏不剥夺条件4、破坏循…

Ceph文件系统

目录 一、环境准备 二、什么是文件系统 三、ceph块存储与文件系统区别 四、创建ceph文件系统 1、启动MDS服务 2、创建存储池 3、创建Ceph文件系统 4、客户端挂载 一、环境准备 Ceph集群搭建参照&#xff1a;Ceph集群部署_桂安俊kylinOS的博客-CSDN博客 以下Ceph存储实…

springcloud22:sentinal的使用

sentinal对比&#xff08;分布式系统的流量防卫&#xff09; 监控保护微服务 Hystrix 需要自己去手工搭建监控平台&#xff0c;没有一套web界面可以进行细粒度化的配置&#xff0c;流控&#xff0c;速率控制&#xff0c;服务熔断&#xff0c;服务降级… 整合机制&#xff1a;se…

外卖项目08---Linux

目录 一、 Linux简介 119 二、Linux安装 120 三、常用命令 122 3.1Linux命令初体验 3.1.1 command [-options] [parameter] 3.2Linux常用命令---文件目录操作命令-ls&-cd&-cat 124 3.2.1list 3.2.2 cd 3.2.3 cat 3.3 Linux常用命令---文件目录操作命令…

9.前端笔记-CSS-CSS三大特性

三大特性&#xff1a;层叠性、继承性、优先级 1、层叠性&#xff08;覆盖性&#xff09; 给相同的选择器设置相同的样式&#xff0c;此时一个样式会覆盖&#xff08;层叠&#xff09;其他冲突的样式。 层叠性原则&#xff1a; 同一选择器&#xff0c;样式冲突&#xff0c;遵…

OpenMV输出PWM,实现对舵机控制

OpenMV的定时器官方函数介绍&#xff1a;Timer类 – 控制内部定时器 目录 OpenMV的PWM资源介绍 为什么要用OpenMV输出PWM OpenMV的PWM资源分配 资源 注意 建议 PWM输出代码 代码讲解 Timer Timer.channel tim.channel与Timer.channel区别 Timer.channel解析 OpenM…

Iframe通信

跨域的种类 一般有两种形式的跨域问题&#xff1a; ①使用XmlHttpRequest(XHR)或者使用AJAX发送的POST或者GET请求。这种形式的跨域是&#xff1a;前端页面与后端进行的跨域请求。 ②父子页面之间进行的DOM操作&#xff08;父子窗口之间的document操作&#xff09;。这种形式…

使用XShell、XFTP 连接 win7 虚拟机(windows、Linux无法远程登录问题)

文章目录前言出错原因&#xff08;题外话&#xff09;那么我们为什么要使用 SSH 连接开始操作&#xff08;Windows7&#xff09;首先进行 SSH 测试获取所需的openSSH文件安装openSSH添加环境变量ssh测试发布ssh服务开始操作&#xff08;Linux&#xff0c;以Ubuntu为例&#xff…

Linux启动流程分析

一、Linux启动流程图 二、硬件启动流程 2.1、POST Linux开机加电后&#xff0c;系统开始开机自检&#xff0c;该过程主要对计算机各种硬件设备进行检测&#xff0c;如CPU、内存、主板、硬盘、CMOS芯片等。主要完成检测硬件能否满足运行的基本条件&#xff0c;叫做“硬件自检(P…