百年百圖の中國(1900-1999):另類python爬蟲和PIL拼圖
標題有點長,也有點怪。前半部分文藝向,後半部分python技術向。目的就是用PIL庫得到100張圖的拼圖(成果圖見文末)。
一、百年百圖の中國(1900-1999)
看理想有篇文章,叫《100張照片里的中國》(其實是轉載自單向街書店的),整理了從1900至1999年,20世紀中國每一年的一張照片。從這些定格的畫面里,我們能看到當時的人物面貌和歷史痕迹。每張圖都有簡短的注釋,上圖便是1960年的照片,備註的文字為:
「全民皆兵是毛澤東在20 世紀 50 年代後期提出的做好反侵略戰爭準備和全民防衛思想;平時工作與戰時準備結合起來,要求國防建設和部隊教育訓練必須從戰爭實際出發,必須以人民戰爭基本理論和要求為基礎。」
還有「一生詩意千尋瀑,萬古人間四月天」、時年12歲的林徽因:
還有齊白石,以前看過《白石老人自述》,自傳里涉及其晚年時各種換妻子、生孩子,一家子的輩分、年齡與人物關係非常複雜,至今印象深刻。摘錄一段,感興趣地可以試著繪製出人物關係圖譜:(一九三七年,77歲)
六月二十三日,卽陰曆五月二十六日,寶珠生了個男孩,這是我的第七子,寶珠生的第四子。我在日記上寫道:「二十六日寅時,鐘錶乃三點二十一分也。生一子,名曰良末,字紀牛,號耋根。此子之八字:戊寅,戊午,丙戌,庚寅,為炎上格,若生於前清時,宰相命也。」我在他的命冊上批道:「字以紀牛者,牛,丑也,記丁丑年懷胎也。號以耋根者,八十為耋,吾年八十,尚留此根苗也。」十二月十四日,孫秉聲生,是良遲的長子。良遲是我的第四子,寶珠所生的第一子,今年十八歲,娶的是獻縣紀文達公後裔紀彭年的次女。寶珠今年三十七歲已經有了孫子啦,我們家,人丁可算興旺哪!美中不足的是:秉聲生時,我的第六子良年,乳名叫作小翁子的,病得很重,隔不到十天,十二月二十三日死了,年纔五歲。
而作為一隻喜歡看老照片的吃瓜群眾,順著文中的藤蔓還能摸到諸多攝影集、紀錄片。比如「新浪潮祖母」阿涅斯·瓦爾達導演的《北京的星期天》,一部關於 50 年代北京的紀錄片。沒看錯,就是1955年,很早很早,對不對,好奇的可以去B站看看,20分鐘左右,不長。
B站:北京的星期天:法國紀錄片大師鏡頭下1955年的彩色北京二、另類python爬蟲和PIL拼圖
安利了那麼多,該講到標題後半部分了。在津津有味的閱讀看理想的原文不到一半時,便忍不住跑去看了《北京的星期天》,之後也沒了耐心繼續看篇幅蠻長的原文,再者單純的下滑頁面,依舊無法全局式的看到百年來的變化,於是決定把這100張照片用python爬蟲爬取下來,再老樣子用PIL庫進行拼圖,正好10X10的布局,完美。
但想快速寫個爬蟲爬取照片時發現原文照片是JS非同步載入出來的,需要用無界面瀏覽器selenium+PhantomJS,或者執行這部分JS代碼,由於一直沒怎麼用過這倆,而且滿腦子想著三下五除二快速爬完了事,還等著美滋滋的拿到拼圖好好欣賞。
2.1 另類python爬蟲
將載入後的網頁源代碼直接複製下來並設置為text,然後直接用lxml進行提取照片url並下載。
(代碼為py2.7)#! /usr/bin/env pythonn#coding=utf-8nnimport requests nimport urllibnfrom lxml import etreentext=n <!DOCTYPE html>n <!--headTrap<body></body><head></head><html></html>--><html>n <head>n .....................................n......................................... nndom = etree.HTML(text)ntry:n img_src=dom.xpath(//img/@data-src)n print len(img_src)#105個n #print img_srcn for i in range(4,len(img_src)-1): #前四張和最後一張剔除n try:n print i-3n path="./100Picture/{}.jpg".format(i-3) #下載的圖片格式從1開始#1.jpgn urllib.urlretrieve(img_src[i],path)n except:print "image error"nexcept:print "img_src error!"n
2.2 PIL庫實現多圖拼接
拿到這100張照片後,就可以三板斧呼哧呼哧地耍過去了。
2.2.1 圖片重命名
上文爬取圖片時就已經命名為1.jpg-100.jpg了,所以這一步可以跳過,若你手頭有其他圖片集,可以備份後進行如下操作:
import osnpath = r"C:/Users/Administrator/Desktop/100Picture/"nfile_list = os.listdir(path)nsaved_path = os.getcwd() #C:UsersAdministratorDesktopnos.chdir(path)nni = 1n#列印目錄下所有文件: str格式nfor file in file_list:n #print filen new_file = "#%s.jpg"% str(i)n os.rename(file, new_file)n i += 1nos.chdir(saved_path)n
2.2.2 查看照片格式
由於第三部拼圖時需要確保每張縮略圖的大小統一,所以必須提前查看所有照片格式,主要是大小,確定長寬下限,本次分別為500和417:
from PIL import Imagenimport os, sysnn#查看每張圖格式、大小ni=1nj=0nwhile i<101:n try:n im = Image.open("C:/Users/Administrator/Desktop/100Picture/%s.jpg" % i)n print im.format, im.size, im.moden i+=1n j+=1n except IOError:n i+=1nprint jn
2.2.3 PIL拼圖
所有100張圖,均生成為400X400的縮略圖,布局成10X10的方式,需要總畫布大小為4000X4000。其他照片集可以自行DIY。
from PIL import Imagenimport os, sysnmw =400 #每張圖大小:長度n#若不想設置成正方形 #例如:wh=300nms = 10 #列數。每行幾張圖nmsize = mw * msntoImage = Image.new(RGBA, (4000, 4000)) #畫布大小nnfor y in range(1, 11):n for x in range(1, 11):n #try-except:跳過打不開的圖片n try:n fromImage = Image.open("C:/Users/Administrator/Desktop/100Picture/%s.jpg" % str(ms*(y-1)+x))n fromImage =fromImage.resize((400, 400), Image.ANTIALIAS)n toImage.paste(fromImage, ((x-1) * mw, (y-1) * mw))n except IOError:n passnntoImage.show()ntoImage.save(C:/Users/Administrator/Desktop/100Picture_IM.jpg) n
歷經千辛萬苦,得到最終效果圖如下,由左向右、由上向下,從左上角到右下角依次對應1900-1999年的照片:
想要全部100張照片的,網盤鏈接: https://pan.baidu.com/s/1pLTzmuJ 密碼: 8qki(侵刪)
(完)推薦閱讀: