百年百图の中国(1900-1999):另类python爬虫和PIL拼图

2018-08-21 14:38:20 浏览数 (1)

标题有点长,也有点怪。前半部分文艺向,后半部分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)

代码语言:javascript复制
#! /usr/bin/env python
#coding=utf-8

import requests 
import urllib
from lxml import etree
text='''
    <!DOCTYPE html>
    <!--headTrap<body></body><head></head><html></html>--><html>
        <head>
   .....................................
.........................................  
'''
dom = etree.HTML(text)
try:
    img_src=dom.xpath('//img/@data-src')
    print len(img_src)#105个
    #print img_src
    for i in range(4,len(img_src)-1): #前四张和最后一张剔除
        try:
            print i-3
            path="./100Picture/{}.jpg".format(i-3) #下载的图片格式从1开始#1.jpg
            urllib.urlretrieve(img_src[i],path)
        except:print "image error"
except:print "img_src error!"

2.2 PIL库实现多图拼接

拿到这100张照片后,就可以三板斧呼哧呼哧地耍过去了。

2.2.1 图片重命名

这部分在爬取图片时就已经命名为1.jpg-100.jpg了,所以本次可以跳过,若你手头有其他图片集,可以需要备份后进行如下操作:

代码语言:javascript复制
import os
path = r"C:/Users/Administrator/Desktop/100Picture/"
file_list = os.listdir(path)
saved_path = os.getcwd()  #C:UsersAdministratorDesktop
os.chdir(path)

i = 1
#打印目录下所有文件: str格式
for file in file_list:
   #print file
   new_file = "#%s.jpg"% str(i)
   os.rename(file, new_file)
   i  = 1
os.chdir(saved_path)

2.2.2 查看照片格式

由于第三部拼图时需要确保每张缩略图的大小统一,所以必须提前查看所有照片格式,主要是大小,确定长宽下限,本次分别为500和417:

代码语言:javascript复制
from PIL import Image
import os, sys

#查看每张图格式、大小
i=1
j=0
while i<101:
    try:
        im = Image.open("C:/Users/Administrator/Desktop/100Picture/%s.jpg" % i)
        print im.format, im.size, im.mode
        i =1
        j =1
    except IOError:
        i =1
print j

2.2.3 PIL拼图

所有100张图,均生成为400X400的缩略图,布局成10X10的方式,需要总画布大小为4000X4000。其他照片集可以自行DIY。

代码语言:javascript复制
from PIL import Image
import os, sys
mw =400 #每张图大小:长度
#若不想设置成正方形 #例如:wh=300
ms = 10  #列数。每行几张图
msize = mw * ms
toImage = Image.new('RGBA', (4000, 4000))  #画布大小

for y in range(1, 11):
    for x in range(1, 11):
        #try-except:跳过打不开的图片
        try:
            fromImage = Image.open("C:/Users/Administrator/Desktop/100Picture/%s.jpg" % str(ms*(y-1) x))
            fromImage =fromImage.resize((400, 400), Image.ANTIALIAS)
            toImage.paste(fromImage, ((x-1) * mw, (y-1) * mw))
        except IOError:
            pass

toImage.show()
toImage.save('C:/Users/Administrator/Desktop/100Picture_IM.jpg') 

历经千辛万苦,得到最终效果图如下,由左向右、由上向下,从左上角到右下角依次对应1900-1999年的照片:

0-100years_100Picture_IM.jpg

想要全部100张照片的,可去主页简介里的某号后台自取。(侵删) (完)

0 人点赞