需要的技术:Python、Flask、requests、BeautifulSoup
前言 #
很久之前有接触过人家写的【快捷指令-下载小红书无水印图片】
当时觉得「快捷指令」很厉害!就点进去研究一下,发现根本看不懂。
后来接触多了 Python爬虫 🦎,其实无水印图片下载只是用 requests
请求网页版的小红书然后用 BeautifulSoup
解析网页找到图片链接,再用 requests
请求图片链接就可以下载图片了。由于网页版里的图片本身没有带水印,所以下载下来的图片就是无水印的了。
「快捷指令」只是把手机复制小红书的分享链接后把分享链接中的URL提取出来,然后给到电脑处理下载后,或者提取图片链接返回给手机的「快捷指令」,「快捷指令」再根据链接保存到手机相册就可以了。
所以我们的思路很简单:
- iPhone 使用「快捷指令」从小红书的 “复制链接” 中提取 “URL” ,这个 “URL” 就是小红书的网页版链接。把这个网页链接发送给电脑(电脑搭建一个服务接收)。
- 本地电脑用 Python 的 Flask 框架搭建一个服务,监听一个端口,接收到这个“URL”后,用 Python 的 requests 模块请求这个链接,然后用 BeautifulSoup 模块解析网页,找到图片的链接。
- 获取 图片链接 后可以用本地电脑下载图片或把图片链接发给手机的「快捷指令」,让手机的「快捷指令」去下载图片。
那接下来,来看看基本的小操作吧。然后后面再一点一点去优化吧!
「快捷指令」提取URL #
首先我们思路先是在小红书中,复制链接 🔗:
从粘贴板中获取复制的文本然后提取里面的URL链接,然后把提取到的URL放到备忘录中。后面正式步骤我们会把提取出来的URL发送给服务器(也就是搭建了服务的家里的电脑)。 只要同意后我们就可以轻松获得这其中的 URL 链接,这个链接其实就是小红书的网页版选择“允许一次”它后面就每执行一次问你一次,所以我们选择“始终允许”会方便一点。获取 URL链接 后,再把 URL链接 推送给服务器,或是家里的电脑来处理。
「Flask」接收URL #
我们接下里的操作是:
- 用Python搭建起一个服务:Flask 应用
- 它会监听一个端口,通过这个端口来获取到这个图片链接
- 然后让 Python 爬虫爬取出图片链接
- 有了图片的链接
- 在电脑上自动下载
- 或是把链接推送回给手机,让手机去下载就好了。
- 下载python
- 在终端下载 Flask:
pip3 install Flask
我们在本地电脑 VSCode 写一个 app.py
👇
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/xhs', methods=['POST'])
def process_url():
# 获取JSON数据
data = request.json
url = data.get('url')
# 返回结果
return jsonify({'result': url})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001)
这上面写完,用 python3 app.py
或者 python app.py
来启动这个脚本,它会监听本地5001端口服务。
- 我们本地的ip地址:
127.0.0.1
- 但是局域网里关于自己电脑的ip地址,每个人电脑都是不一样的,比如我的就是
192.168.254.110
。这个地址不用怕告诉别人,因为人家并访问不了你局域网的ip地址。我们的ip地址并非公网ip地址,公网的才怕人家搞你。非公网的,一般不「内网穿透」我自己想访问都访问不到… - 后面的5001是端口号,你可以自己改,5000也行,都可以… 如果提示被占用了就再改改…
- 所以我们的服务就搭建在
192.168.254.110:5001/xhs
上,记得要用POST请求 - 可以下载「postman」这个软件或是「apipost」来进行「post请求」,我们用浏览器的访问ip地址的请求一般都是「get请求」
可以看到这上面就是个简单的Python服务,它监听5001端口,然后接受到POST请求,然后把POST请求的JSON数据返回。
我们接下里两个步骤:
- 先暂时用 apipost的请求 来代替手机「快捷指令」发送过来的url
- 我们把python爬取的任务写完:
- 拿到的这个数据去用python爬取「小红书网页版本的链接」
我写了以下代码来获取,如果会python爬虫的小伙伴也可以自己去小红书的网页版看看网页的DOM结构,然后来爬,如果找不到图片链接可以看以下来获取灵感👇
需要注意:这是2024年1月1日的脚本,如果小红书有改动,这个脚本可能就没用了,但是思路不变!!!
from flask import Flask, request, jsonify
import requests
from bs4 import BeautifulSoup
app = Flask(__name__)
headers = headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Referer': 'https://www.xiaohongshu.com/',
# 'Cookie':'' #必要时候带上Cookie
}
@app.route('/xhs', methods=['POST'])
def process_url():
# 获取JSON数据
data = request.json
url = data.get('url')
data = {
'status': 200,
'img':'',
'msg':''
} # 等等要返回的数据
try:
res = requests.get(url,headers=headers)
res.encoding = 'utf-8'
html = res.text
soup = BeautifulSoup(html, 'lxml')
# 可以把爬取的网页写下来看看真正爬取到的结构
with open('test.html', 'w', encoding='utf-8') as f:
f.write(str(soup))
# 获取图片名称
img_title_area = soup.find('meta', attrs={'name':'og:title'})
img_title = img_title_area['content']
# 获取图片链接
img_area = soup.findAll('meta', attrs={'name':'og:image'})
num = 0
img_data = []
for i in img_area:
# 给图片1号 2号.... 加一下后缀~
num+=1
img_name = img_title + '.png'
if len(img_area) > 1 and num == 2:
img_name = img_title + '-' + str(num) + '.png'
img_url = i.get('content')
### 【这一部分是本地下载,如果你只是想下载到手机,可以去掉这段】
try:
img_res = requests.get(img_url,headers=headers)
img_res.encoding = 'utf-8'
with open('img/'+img_name, 'wb') as f:
f.write(img_res.content)
except:
continue
### 【👆 这就是这7行.. 记得如果要使用,在当前目录新建一个叫 img 的文件夹哦😁】
##【下面就是整理一下数据~】
img = {
'name':img_name,
'url':img_url
}
img_data.append(img)
data['img'] = img_data
data['status'] = 200
data['msg'] = '✅ 获取成功'
except:
data = {
'status': 403,
'img': '',
'msg': '❌ 获取失败... 程序出错'
} # 等等要返回的数据
# 返回结果
return jsonify(data)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001)
好了我们本地试一下:
好!很好! 非常好! 🎉
其实思路只要正确,一般都不会出错的…
接下里我们不就是用手机的「快捷指令」来发送「小红书的网页链接」到这个接口就可以了吗?!对吧!嘻嘻😁
接下里我们去「快捷指令」处操作吧👇
「快捷指令」发送 URL 到 「Flask」 #
没错! 跟着这样操作吧,相信聪明的你即使不用我讲解也能看得懂!
- 词典:就是 Json -
{ }
- 重复:就是 List -
[ ]
去吧!孩子! 小红书里的小姐姐正在等着你呢!!🫡
注意注意⚠️
请不要把这些技术用在不好的地方,例如涉及版权问题和人文道德问题,技术无罪,但是别爬取人家小姐姐的照片去干坏事啊喂!😡
最后你肯定还是有很多疑问,例如:
Q1:局域网才能用? #
是的,如果你想在家以外的地方也能使用上这项服务,要么就买个便宜的服务器,然后把这个服务部署在服务器上。 或者学习一下内网穿透把家里的服务暴露到外网,这样就可以在外网访问到这个服务了。
Q2:占用终端窗口? #
服务一启动,占用终端窗口,不能关掉,很不优雅?!
没事,这个可以使用像gunicorn之类的WSGI HTTP服务器,还可以使用systemd来管理服务。这个技术后面会讲解,使用systemd管理服务,可以让服务开机自启,还可以管理服务的重启、停止等。而且不会有碍眼的终端窗口在你的屏幕上,它会在后台静默运行着。灰常优雅~
Q3:脚本优化问题 #
你这些脚本看起来很随便喔,比如我要是不复制url 给你,你不就报错了…
程序可以后面继续完善,甚至可以下载视频,或者区分出谁家的网页,抖音的视频也可以下载下来。
好了,本期分享就到这里了,最近写的文章是越来越多了,但是也真的是忙,我已经很久没打游戏了,希望以后会有多点时间可以学习和打游戏吧~ 下期再见咯👋