Python通过URL下载图片时的中文、空格处理
對于如何從目標網站如何爬取數據不是本章將要描述的重點,有興趣的同學可以去其它博客尋找答案。
?
將我遇到的問題進行簡化:已經獲取到一些URL了,每個鏈接都是指向網站中的一個圖片,現在需要把這些圖片都下載下來。但是在下載一些圖片時,報錯了。因為涉及到網絡通信和文件的讀寫,所以對這些容易發生錯誤的地方加了 try...except... 可以打印出具體遇到的錯誤。
?
1. 先看一下我挑出的url數據。文件保存時默認用的GBK編碼保存的。用Pycharm打開時發現有亂碼,并且提示用gbk編碼格式重新打開,reload后就顯示正常了。
creative_id,pack_id,template_id,app_name,category_id,img_url 1000073,232,1,com.finaccel.android,1272,http://shareitcpi.rqmob.com/creatives/2020-02-15/aqchkyedah582ebbc371d02464016e7aec89bda418__FILE_CM____FILE_CM480_720__.jpg 1000073,232,1,com.finaccel.android,1272,http://shareitcpi.rqmob.com/creatives/img/2020-02-25/compress-147033907-v26f5wvgps6yglv2z48i01hnenhvticb.jpg 1000446,234,54,com.indiaBulls,1272,http://shareitcpi.rqmob.com/creatives/img/2020-03-11/compress-2113000390-o8qmg04quw35ck7bdwv4uykzmzbbanfn.png 1000081,234,4,com.indiaBulls,1272,http://shareitcpi.rqmob.com/creatives/2020-02-17/rjdkwm9jwgStock Market game.jpg_1080px x 270px-_副本_副本.jpg 1000080,234,2,com.indiaBulls,1272,http://shareitcpi.rqmob.com/creatives/2020-02-17/snbu2nfehs微信圖片_20200216202007.png2. 先看代碼
# -*- coding: utf-8 -*- import csv import os from urllib.request import urlretrieve import urllib.parse import stringimg_url_file = 'img_url_temp.csv' img_save_path = './img_data' os.makedirs(img_save_path, exist_ok=True) i = 0with open(img_url_file, encoding='gbk') as csvfile:csv_reader = csv.reader(csvfile)birth_header = next(csv_reader)print(birth_header, "\n") # ['creative_id', 'pack_id', 'template_id', 'app_name', 'category_id', 'img_url']print("======================")for row_list in csv_reader:try:img_url = row_list[5]# img_url = urllib.parse.quote(img_url, safe=string.printable).replace(" ", "%20")urlretrieve(img_url, 'img_data/'+str(row_list[0])+'#'+str(row_list[1])+'#'+str(row_list[2])+'#'+str(row_list[3])+'#'+str(row_list[4])+'#'+'.jpg')except Exception as e:print("error:", e)print("error_load_img:", img_url)print(row_list)i += 1print("+++++++++++++++++")print("Error number: ", i)不得不說,使用urlretrieve(url, filename) 可以很方便的將指定鏈接的圖片下載到指定位置,簡直是傻瓜式操作。
?
3. 錯誤處理
通過打印異常,可以看到有兩個錯誤:
a. url中不能包含控制字符
b. url只支持ascii碼值
"E:\Program Files\Python374\python.exe" F:/my_workspace/py_workspace/load_material_photo1.py ['creative_id', 'pack_id', 'template_id', 'app_name', 'category_id', 'img_url'] ====================== error: URL can't contain control characters. '/creatives/2020-02-17/rjdkwm9jwgStock Market game.jpg_1080px x 270px-_副本_副本.jpg' (found at least ' ') error_load_img: http://shareitcpi.rqmob.com/creatives/2020-02-17/rjdkwm9jwgStock Market game.jpg_1080px x 270px-_副本_副本.jpg ['1000081', '234', '4', 'com.indiaBulls', '1272', 'http://shareitcpi.rqmob.com/creatives/2020-02-17/rjdkwm9jwgStock Market game.jpg_1080px x 270px-_副本_副本.jpg'] +++++++++++++++++ error: 'ascii' codec can't encode characters in position 36-39: ordinal not in range(128) error_load_img: http://shareitcpi.rqmob.com/creatives/2020-02-17/snbu2nfehs微信圖片_20200216202007.png ['1000080', '234', '2', 'com.indiaBulls', '1272', 'http://shareitcpi.rqmob.com/creatives/2020-02-17/snbu2nfehs微信圖片_20200216202007.png'] +++++++++++++++++ Error number: 2總結來說就是,我的url中包含ascii的控制字符和中文,直接的導致了error。
順便說一句,ASCII碼其實是包含控制字符和可打印字符,一共128個,控制字符是不能打印出來的。
可以使用
urllib.parse.quote(url)來對url中的特殊字符進行url的encode,根據某個RFC的定義,會把其中的中文和特殊字符都編碼為%XX的格式,用%帶兩個十六進制數代表一個字符,如果是一個漢字需要3個%XX來表示。因為encode時,使用的utf-8編碼,在utf-8中一個漢字占了三個字節,和Unicode中每個漢字占兩個字節還是非常不同的。
既然是大家都公認的RFC文檔中定義的,那么將編碼后的rul字符串直接copy到瀏覽器中應該也是可以訪問的。
http://shareitcpi.rqmob.com/creatives/2020-02-17/rjdkwm9jwgStock Market game.jpg_1080px x 270px-_副本_副本.jpg -> http%3A//shareitcpi.rqmob.com/creatives/2020-02-17/rjdkwm9jwgStock%20Market%20game.jpg_1080px%20x%20270px-_%E5%89%AF%E6%9C%AC_%E5%89%AF%E6%9C%AC.jpg但是發現http后面的冒號也被編碼為%3A了,這時瀏覽器肯定是不認了。其實如果只保留http://后面的uri,瀏覽器也是認的,可以自動給添加http://。但是我們的urlretrieve()函數還不行。
這里想到兩個解決辦法:
a. quote(url)前先把url前面的http://或https://去掉,在結束后給拼接回去。
b. 在quote(url)中使用參數
safe=string.printable這樣就只會替換中文,像冒號這種字符就不會被替換了,畢竟冒號屬于可打印字符。新的問題就出現了,空格也屬于可打印字符,但是url是不認它的。需要再專門把空格替換為%20。最后就多加一句
img_url = urllib.parse.quote(img_url, safe=string.printable).replace(" ", "%20")?
總結
以上是生活随笔為你收集整理的Python通过URL下载图片时的中文、空格处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小白的cannot get interf
- 下一篇: 如何选择与自己合适的服装颜色搭配