本帖最后由 朱焱伟 于 2024-8-11 18:06 编辑
爬取Reddit收藏夹
目的
如何保存Reddit上收藏夹和点赞过的所有帖子?
saveddit使用
经过对比尝试,发现github.com/p-ranav/saveddit较好,接下来说明使用saveddit
爬取reddit收藏夹的过程。
创建python3环境
conda create -n py310 python=3.10.6
conda activate py310
conda update -n base -c defaults conda
安装saveddit
conda install saveddit
或pip3 install saveddit
。
详见github.com/p-ranav/saveddit说明。
创建reddit脚本应用
在https://www.reddit.com/prefs/apps创建Script脚本类型的应用,以便下面使用其应用id和密钥来调用Reddit API
填写认证信息
安装好saveddit后,应该已经有了yaml格式的配置文件,来打开编辑。
vim ~/.saveddit/user_config.yaml
配置文件里,需要按https://www.reddit.com/prefs/apps网页上自己创建的应用情况,在yaml里替换配置为你的Reddit API认证信息。
reddit_client_id: '你的脚本应用id'
reddit_client_secret: '你的脚本应用密钥'
reddit_username: '你的reddit用户名'
测试运行
至此,应该可以运行,爬一下自己点赞的前几条记录测试下。
saveddit user users 你的reddit用户名 upvoted -l 5
防盗链图片
* Processing `https://i.redd.it/6h97arsgih171.jpg`
* This is a direct link to a jpeg file
- <urlopen error EOF occurred in violation of protocol (_ssl.c:997)>
* Saving submission.json
* Saving top-level comments to comments.json
- 100%|████████████████████| 8/8 [00:00<00:00, 86037.01it/s]
* Saved to output/www.reddit.com/u/XXX/upvoted/001_XXX
之前的运行确实可以下载一些帖子的内容(包括图片和评论),但如果遇到i.redd.it
开头的一些图片链接,就下载不下来,比如i.redd.it/6h97arsgih171.jpg。
`urllib.request.urlretrieve(submission.url, output_path)`
这行代码会报错`<urlopen error EOF occurred in violation of protocol (_ssl.c:997)>`
可以查看saveddit源码看看是什么原因,首先定位saveddit安装位置:
conda activate py310
whereis saveddit
pip3 show saveddit
从上面输出可以看到saveddit安装位置,我们定位一下要修改的源码的位置,比如:
vim ~/anaconda3/envs/py310/lib/python3.10/site-packages/saveddit/submission_downloader.py
可以看到是urllib.request.urlretrieve(submission.url, output_path)
这句话下载i.redd.it
开头的图片链接会有ssl相关报错。具体怎么改这个urllib里的urlretrieve传参,我没搞明白。不过试了一下curl可以正常下载图片,那就把urllib.request.urlretrieve用运行curl命令的办法替换。修改代码saveddit/submission_downloader.py
# def download_direct_link(self, submission, output_path):
# try:
# urllib.request.urlretrieve(submission.url, output_path)
# except Exception as e:
# self.print_formatted_error(e)
def curl_download(self,url, output_path):
import subprocess
curl_command = ['curl', '-o', output_path, url]
subprocess.run(curl_command)
def download_direct_link(self, submission, output_path):
try:
self.curl_download(submission.url, output_path)
# urllib.request.urlretrieve(submission.url, output_path)
except Exception as e:
self.print_formatted_error(e)
试了下,这样可以正常下载了。能跑就行,那就继续凑合用了。
遇到一些https://i.redd.it/
开头的链接,简单地curl可能下不下来,可以换用gallery-dl来替换。
python3 -m pip install -U gallery-dl
whereis gallery-dl
gallery-dl https://i.redd.it/zbthk3rrb57d1.jpeg
gallery-dl -D . https://i.redd.it/zbthk3rrb57d1.jpeg
def curl_download(self,url, output_path):
home_directory = os.path.expanduser('~')
gallery_dl_path = os.path.join(home_directory, 'anaconda3/envs/py310/bin/gallery-dl')
output_folder = output_path.split('/files')[0]+'/files'
curl_command = [gallery_dl_path, '-D', output_folder, url]
result = subprocess.run(curl_command, capture_output=True, text=True)
if result.returncode == 0:
print("Download successful!")
else:
print(f"Error: {result.stderr}")
-d, --destination PATH Target location for file downloads
-D, --directory PATH Exact location for file downloads
gallery-dl自身也支持不少网站,详见gallery-dl/supportedsites.md,有兴趣可以深入♂探索。
保存学习资料
那就回到最初的目标,爬一下自己收藏夹和点赞过的帖子,其他具体用法看saveddit官方说明。
conda activate py310
saveddit user users 你的Reddit用户名 saved -l 1000000 -o output 2>&1 | tee log.saved.txt
saveddit user users 你的Reddit用户名 upvoted -l 1000000 -o output 2>&1 | tee log.upvoted.txt
相关链接
i.redd.it图片直接加载
假如我要打开https://i.redd.it/6h97arsgih171.jpg
这种链接,由于网站限制,并不能直接ctrl+s来保存。
搜了下,倒是有个火狐扩展可以专门干这个事addons.mozilla.org/en-US/firefox/addon/load-reddit-images-directly Load Reddit Images Directly,代码详见github.com/nopperl/load-reddit-images-directly 。代码可以参考下,不过这个火狐扩展用起来体验并不好。
有人发issue问这扩展能不能改成用户脚本让人更方便使用I wonder, is there a chance you could make an userscript out of this? #5,作者好像没有打算。
我找到另外一个油猴脚本使用体验不错(比上面那个火狐扩展好,可以替代它):sleazyfork.org/zh-CN/scripts/109-handy-image。代码详见github.com/Owyn/HandyImage
其他
reddit上也有一些相关讨论,我尝试对比了下,其他工具好像没saveddit好用。至于为啥用起了reddit,那是因为我的小蓝鸟账号已经被封禁了两个。众里寻他千百度,一夜回到解放前。雄关漫道真如铁,而今迈步从头越。希望这次不要再搞没收藏夹了。我现在只想用我的大资料狠狠地塞满你的小硬盘。