Python自動(dòng)解析markdown中的圖片并保存
python自動(dòng)化下載/上傳md中圖片實(shí)在是太方便了
1.起因
為什么需要python來(lái)下載md里面的圖片?原因很簡(jiǎn)單,那就是需要把圖片保存下來(lái),上傳到第二個(gè)圖床(遷移)
對(duì)于阿里云OSS來(lái)說(shuō),有兩種遷移辦法
- 使用官方的數(shù)據(jù)導(dǎo)出功能
- 使用api接口遍歷oss目錄下載所有圖片
這兩種辦法都不是那么方便,所以我選擇了第三種
- 解析本地md文件中的img url,下載圖片并保存到本地
那要怎么做呢?
2.教程
我在github找到了這個(gè)項(xiàng)目 Deali-Axy/Markdown-Image-Parser
作者的代碼寫的很棒,但是README里面卻少了一個(gè)重要的啟動(dòng)教程,那就是你需要在當(dāng)前目錄下創(chuàng)建一個(gè)files文件夾(md文件放到這里面),對(duì)應(yīng)啟動(dòng)項(xiàng)里面開啟的根目錄
if __name__ == '__main__':
files_list = get_files_list(os.path.abspath(os.path.join('.', 'files')))
隨后,執(zhí)行python spider.py,開始運(yùn)行,腳本會(huì)自動(dòng)將md轉(zhuǎn)成html并下載圖片
我將作者的代碼進(jìn)一步細(xì)化,并修改了一部分bug建議使用我fork的版本
https://github.com/musnows/Markdown-Image-Parser
2.1 UnicodeDecodeError
在啟動(dòng)的時(shí)候,你可能會(huì)遇到這個(gè)報(bào)錯(cuò)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbc in position 2: invalid start byt
解決辦法是將打開文件編碼的utf-8 修改成ISO-8859-1
with open(file, encoding='ISO-8859-1') as f:
md_content = f.read()
2.2 request failed
因?yàn)樽髡卟]有寫判斷,此時(shí)就會(huì)出現(xiàn)一個(gè)嚴(yán)重問(wèn)題:本地圖片也會(huì)進(jìn)行requests請(qǐng)求
比如我的md里面就有一些圖片是本地的img/圖片文件名,這個(gè)代碼依舊對(duì)這個(gè)路徑當(dāng)做網(wǎng)絡(luò)路徑進(jìn)行請(qǐng)求,于是就出現(xiàn)了報(bào)錯(cuò)
所以就需要在download_pics函數(shù)中對(duì)url進(jìn)行判斷,這里可以寫成下面的格式(因?yàn)槲抑牢业陌⒗镌芆SS鏈接里面不包含img文件夾,所以img/的圖片是本地文件
def download_pics(url, file,MDfilename):
if 'img/' in url:
print('不處理本地圖片: ', url)
return
但是這樣其實(shí)還是有點(diǎn)呆呆的,我們直接判斷http在不在里面不就知道是不是網(wǎng)絡(luò)圖片了
def download_pics(url, file,MDfilename):
if 'http' not in url:
print('不處理本地圖片: ', url)
return
2.3 圖片保存路徑
默認(rèn)情況下,圖片會(huì)保存到子文件夾下的markdown文件名目錄
targer_dir = os.path.join(dirname,assert_dir)
if not os.path.exists(targer_dir):
os.mkdir(targer_dir)
這樣其實(shí)非常非常不方便管理,有幾個(gè)md文檔就有幾個(gè)md圖片路徑,可太難受了
所以我們需要注釋掉這部分代碼,直接選擇一個(gè)根目錄進(jìn)行圖片的保存
targer_dir ='./files/img/' # 所有圖片都保存到 ./files/img/ 文件夾里面
2.4 try/except
作者代碼里面的最最最大漏洞,那就是沒有對(duì)for循環(huán)里面的請(qǐng)求進(jìn)行try/except
這樣就會(huì)導(dǎo)致,如果有一個(gè)圖片請(qǐng)求失敗,整個(gè)進(jìn)程會(huì)直接終止!
那么問(wèn)題就來(lái)了,即便這個(gè)程序會(huì)在遍歷的時(shí)候打印當(dāng)前處理的文件名字,但這需要用戶去翻命令行輸出,再找到到底是哪一個(gè)圖片發(fā)生錯(cuò)誤,非常非常非常難受!
如果重新執(zhí)行,那就相當(dāng)與把已經(jīng)下好的圖片又重下一遍,浪費(fèi)OSS的流量。
所以我們必須要給for循環(huán)內(nèi)部添加上異常捕獲,如果遇到錯(cuò)誤,就將這個(gè)圖片的url存下來(lái),繼續(xù)往后執(zhí)行!
for file in files_list:
print(f'正在處理:{file}')
with open(file, encoding='ISO-8859-1') as f:
md_content = f.read()
pics_list = get_pics_list(md_content)
print(f'發(fā)現(xiàn)圖片 {len(pics_list)} 張')
for index, pic in enumerate(pics_list):
try:
print(f'正在下載第 {index + 1} 張圖片...')
MDfilename = os.path.basename(file) # 當(dāng)前處理的md文件的名字
download_pics(pic, file,MDfilename)
time.sleep(0.5) # 避免下載超速
except KeyboardInterrupt:
os.abort()
except:
print(traceback.format_exc())
if MDfilename not in err_img:
err_img[MDfilename]=[]
# 添加圖片
err_img[MDfilename].append(pic)
print("圖片獲取錯(cuò)誤:",pic)
time.sleep(1)
print(f'處理完成。')
write_file('err.json',err_img)
print(f'寫入err完成')
完整代碼見我的github倉(cāng)庫(kù)
2.5 上傳到lsky圖床
現(xiàn)在我要遷移的圖床是lsky,所以為了方便,可以在將圖片保存到本地的同時(shí),將圖片上傳到lsky圖床
注意,上傳之前,請(qǐng)?jiān)?strong>用戶組將圖片上傳的格式改為原始文件命名,否則重命名了那就什么都沒了!

還發(fā)現(xiàn)了一個(gè)離譜的問(wèn)題,那就是一些圖片上傳了之后,lsky還是會(huì)給他改名字?。?!

比如這個(gè)gif,他的alt里面是原始名字,但是url并不是?。?!你說(shuō)這離譜不
解決方法那就是把本地的圖片打一個(gè)壓縮包,傳到云服務(wù)器后臺(tái)存儲(chǔ)路徑中覆蓋一遍,把沒有的圖片給添加上
unzip -o ~/docker/img.zip -d ~/docker/lsky/storage/app/uploads/23/02
上傳之前,先獲取token
def lsky():
url = "服務(wù)器地址/api/v1/tokens"
params = {
'email':'賬戶郵箱',
'password':'密碼'
}
res = requests.post(url, params=params) # 請(qǐng)求api
return res.json()
結(jié)果如下
{'status': True, 'message': 'success', 'data': {'token': '這里會(huì)返回token'}}
隨后是上傳的代碼,注意蘭空必須要用open 'rb'重新打開一邊圖片,所以參數(shù)給img_path也就是圖片的路徑即可
# 蘭空?qǐng)D床
def lsky_upload(img_path:str):
url = "你的蘭空?qǐng)D床服務(wù)器/api/v1/upload"
header = {
"Authorization": "Bearer 你的蘭空token",
"Accept": "application/json"
}
img = open(img_path, 'rb')
params = {'strategy_id': 1}
myfiles = {'file': img}
res = requests.post(url, headers=header, params=params,
files=myfiles) # 請(qǐng)求api
return res.json()
在download_pics的末尾添加如下代碼,并對(duì)蘭空?qǐng)D床的返回值進(jìn)行判斷,如果上傳錯(cuò)誤,同樣添加到錯(cuò)誤圖片中!
# 上傳lsky
res = lsky_upload(img_path=f"{targer_dir}/{filename}")
print(res)
if not res['status']:
global err_img
if MDfilename not in err_img:
err_img[MDfilename]=[]
err_img[MDfilename].append(url)
print("蘭空上傳錯(cuò)誤!",url)
time.sleep(1)
上傳成功的返回值status是True
3.開始自動(dòng)化上傳
將上面的bug修改好了之后,就可以正式運(yùn)行,在保存圖片到本地的同時(shí),上傳到蘭空?qǐng)D床了!

圖片也都成功保存到本地了

上傳完畢之后,也能在err里面看到錯(cuò)誤的圖片路徑,以便重新處理。
可以看到這里面有一部分是gitee和csdn的鏈接,這些圖片有防盜鏈,而且圖片尾部添加了其他字段,導(dǎo)致lsky沒有辦法將其識(shí)別為圖片(卻少圖片格式后綴)
不過(guò)我的目標(biāo)是將阿里云OSS的圖片轉(zhuǎn)到lsky,這些本來(lái)就不是阿里云OSS的圖片和我的目的無(wú)關(guān)!

做完這一切,最讓我感慨的是,我的阿里云oss里面有1g的圖片,實(shí)際用的卻只有下面這一丟丟;其他估計(jì)都是重復(fù)上傳的

到此這篇關(guān)于Python自動(dòng)解析markdown中的圖片并保存的文章就介紹到這了,更多相關(guān)Python解析markdown圖片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python構(gòu)建網(wǎng)頁(yè)爬蟲原理分析
這篇文章主要給大家講解了構(gòu)建網(wǎng)頁(yè)爬蟲的技術(shù)原理以及實(shí)現(xiàn)的邏輯關(guān)系,有興趣的朋友閱讀下吧。2017-12-12
python如何通過(guò)正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容
這篇文章主要介紹了python通過(guò)正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容的操作方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
Python使用Chartify庫(kù)進(jìn)行數(shù)據(jù)分析繪制詳解
這篇文章主要介紹了Python使用Chartify庫(kù)進(jìn)行數(shù)據(jù)分析繪制,它提供了簡(jiǎn)潔易用的API,讓我們能夠快速地繪制出美觀且專業(yè)的圖表,無(wú)需像使用matplotlib和seaborn那樣花費(fèi)大量時(shí)間去調(diào)整各種復(fù)雜的參數(shù),大大提高了數(shù)據(jù)可視化的效率,需要的朋友可以參考下2025-04-04
Python?Melt函數(shù)將寬格式的數(shù)據(jù)表轉(zhuǎn)換為長(zhǎng)格式
在數(shù)據(jù)處理和清洗中,melt函數(shù)是Pandas庫(kù)中一個(gè)強(qiáng)大而靈活的工具,它的主要功能是將寬格式的數(shù)據(jù)表轉(zhuǎn)換為長(zhǎng)格式,從而更方便進(jìn)行分析和可視化,本文將深入探討melt函數(shù)的用法、參數(shù)解析以及實(shí)際應(yīng)用場(chǎng)景2023-12-12
利用Python如何實(shí)時(shí)檢測(cè)自身內(nèi)存占用
這篇文章主要介紹了利用Python如何實(shí)時(shí)檢測(cè)自身內(nèi)存占用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
基于文件路徑中/?\?//?\\的用法以及絕對(duì)相對(duì)路徑的問(wèn)題
這篇文章主要介紹了基于文件路徑中/?\?//?\\的用法以及絕對(duì)相對(duì)路徑的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02
python requests 庫(kù)請(qǐng)求帶有文件參數(shù)的接口實(shí)例
今天小編就為大家分享一篇python requests 庫(kù)請(qǐng)求帶有文件參數(shù)的接口實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01

