本蒟蒻有個愛好,喜歡保存各個方面的數據,比如錄制電視新聞、下載重要網頁、抄寫消息文章,保存起來 然后放着等長毛,長到3米高就能吃了 。有這么個愛好那自然微博是必去之地,截屏復制截到手疼,更重要的就是下載這個那個微博視頻保存起來。而作為手機一族,微博視頻的操作很讓人迷惑:
如果是豎屏的視頻,那好說,直接點右上角三個點,然后保存到手機,接下來就出現在DCIM里了:
然而橫屏的視頻就很讓人迷惑:點開只給了一個“緩存”:
然后也能看到之前緩存的視頻:
然而就是不知道這些視頻放在哪。。。
。。。。。。。。。。
人不能憋死,於是經過一番地毯式搜索,摸到了這些緩存視頻的保存位置——
——在主存儲目錄下/sina/weibo/.weibo_video_cache_new這個隱藏着的旮旯里。。。
2019-09-21更新:已經改到了\sina\weibo\storage\video_download里,cover里是封面圖,接下來操作的是video文件夾。
(對了,得先能顯示隱藏文件。。。)
里面是一堆文件夾,每個文件夾對應一個視頻
每個文件夾里面有一個config.json記錄視頻信息,還有一個沒后綴名的東西
連接電腦,MTP把這些東西搞出來:
那個json,沒什么新鮮的:
剩下的這個就是操作對象——用視頻播放器打開,直接就能播——
然后我們就看到了這是MPEG4視頻。。。
所以理論上來說把這個文件后面加個.mp4就能看了,然而——現在有120個視頻等着我收拾。。。
這要從頭改到尾,估計手要斷。
於是第一反應就是求助批處理,那么我們面臨這么些個問題:
- 文件夾名、視頻名都是亂的,怎么能夠分別讀取每個文件夾的視頻並批量搞出來?
第一直觀想法是dir,這樣可以列出所有下面的東西。
- 然而dir這種顯示格式很小清新,怎么能夠從中讀出這個那個是什么東西、叫什么名?
dir /?如是說:
顯示目錄中的文件和子目錄列表。
DIR [drive:][path][filename] [/A[[:]attributes]] [/B] [/C] [/D] [/L] [/N]
[/O[[:]sortorder]] [/P] [/Q] [/R] [/S] [/T[[:]timefield]] [/W] [/X] [/4][drive:][path][filename]
指定要列出的驅動器、目錄和/或文件。/A 顯示具有指定屬性的文件。
屬性 D 目錄 R 只讀文件
H 隱藏文件 A 准備存檔的文件
S 系統文件 I 無內容索引文件
L 解析點 - 表示“否”的前綴
/B 使用空格式(沒有標題信息或摘要)。
/C 在文件大小中顯示千位數分隔符。這是默認值。用 /-C 來
禁用分隔符顯示。
/D 跟寬式相同,但文件是按欄分類列出的。
/L 用小寫。
/N 新的長列表格式,其中文件名在最右邊。
/O 用分類順序列出文件。
排列順序 N 按名稱(字母順序) S 按大小(從小到大)
E 按擴展名(字母順序) D 按日期/時間(從先到后)
G 組目錄優先 - 反轉順序的前綴
/P 在每個信息屏幕后暫停。
/Q 顯示文件所有者。
/R 顯示文件的備用數據流。
/S 顯示指定目錄和所有子目錄中的文件。
/T 控制顯示或用來分類的時間字符域。
時間段 C 創建時間
A 上次訪問時間
W 上次寫入的時間
/W 用寬列表格式。
/X 顯示為非 8.3 文件名產生的短名稱。格式是 /N 的格式,
短名稱插在長名稱前面。如果沒有短名稱,在其位置則
顯示空白。
/4 用四位數字顯示年可以在 DIRCMD 環境變量中預先設定開關。通過添加前綴 - (破折號)
來替代預先設定的開關。例如,/-W。
那么 /B這個很耐人尋味:
使用空格式(沒有標題信息或摘要)。
讓咱們試試:
成功單獨搞出來了文件名。
- 有了文件名,怎么根據這些文件名收拾各組數據?
那當然就是for循環。cmd的for很強勢,我們在這里用到這條語法:
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
那么我們就可以這樣把這一堆文件名全都寫進editlib這么個文件里:
for /f "delims=" %%i in ('dir /ad/b') do echo %%i>>editlib
::for /f "格式“ %%變量 in ('命令') do XXX
::delims:cmd的for循環關鍵字,相當於用等號后面的那個東西來進行對數據的分割,這里留空就是“換行”,每讀到dir輸出的一個換行就代表讀到了一個文件夾名,可以換下一個寫入了
::變量要用兩個百分號
::這里的命令就是dir,/ad就是顯示完整目錄
::最后echo全都寫入editlib里。
接下來我們就有了完整的文件夾名列表:
於是接下來的操作就是——
- 循環按照這個表進去每個文件夾里
- 刪掉config.json
- 把里面剩下的東西(這個視頻)拷出來
- 把這個文件拷出來放到上一個目錄里
- 回來
- 刪掉這個文件夾。
那么求助C++來寫這么個批處理:
#include<bits/stdc++.h>
using namespace std;
int main()
{
system("cd.>editlib");
system("cd.>operatorlib.bat");
system("cd.>controllib.bat");//創建這么三個文件
FILE * fout;//用fout寫文件,寫出上面的那套方法到一個批處理里:
fout=fopen("controllib.bat","wb");
fprintf(fout,"@echo off\r\n");
fprintf(fout,"for /f \"delims=\" %%%%i in ('dir /ad/b') do echo %%%%i>>editlib\r\n");//“\“拿來轉義用免得編譯器以為那個雙引號是字符串結束,用4個”%“來fprintf 2個百分號。
fclose(fout);//關文件
system("controllib.bat");//運行一次,然后就有了editlib這個文件夾列表
freopen("editlib","r",stdin);//重定向標准輸入輸出流讀這個editlib
freopen("operatorlib.bat","w",stdout);//按照一定語法輸出到另一個批處理operatorlib.bat里,這就是我們實現這一系列騷操作用的批處理:
string way;//每一個文件夾名
while(cin>>way)//分行讀入
{
string outputa=way;//然並卵
cout<<"cd "<<outputa<<endl;//進到這個文件夾里
cout<<"del config.json"<<endl;//刪掉config.json
cout<<"for /f \"delims=\" %%j in ('dir /b/s') do rename %%j "<<way<<".mp4"<<endl;//故伎重演,用dir /s/b就可以搞出來里面唯一的那個文件的文件名和完整路徑,放入變量%%j里,然后重命名這個文件。
cout<<"copy * .."<<endl;//把它拷出來
cout<<"cd .."<<endl;//回來
cout<<"rmdir /s/q "<<outputa<<endl;//刪掉那個文件夾,准備收拾下一個。
}
fclose(stdin);
fclose(stdout);//關文件
system("operatorlib.bat");//運行一下這個批處理
system("del editlib");
system("del operatorlib.bat");
system("del controllib.bat");//刪掉多余的東西
return 0;
}
編譯好,放進這個目錄里,運行~
搞定。把這個程序刪掉,剩下視頻整理走。
備注:
-
本人是一個蒟蒻,從未在專業角度接受過有關cmd命令及C++的知識傳授,一切僅憑自己摸索搞出來。我可以想見,我這個方法極端的LOW,更好的方法一定層出不窮。還希望各位大神看了勿噴,給新手一些支持,謝謝!
-
實驗證明,微博會把你點了緩存的視頻還有你平時看的沒用的視頻緩存都放進這里。測試表明(MIUI 10.3.2 安全中心 垃圾清理)可以先運行一遍手機的垃圾清理再往外搞文件,刪掉那些沒用的緩存,只留下點過緩存了的。
最后放上這個程序
提取碼:xc1c
操作完畢。光速逃(霧
2019/09/15更新:發現了一處問題,已經修改。
因為未能詳細排查錯誤,忽略錯誤提示就直接應用到了實戰中,結果收集了半個多月的視頻全被rmdir打了水漂。。。
總結經驗教訓:
-
寫程序不能忽略任何錯誤提示,並必須經過仔細、嚴格的測試方可投入使用!要不就是像這樣以白忙活了半個月(甚至更慘)作為代價!!
-
重要資料必須做好備份工作!!!
數據千萬條
備份第一條
操作不備份
數據兩行淚