PythonChallenge系列-P9 图像绘制

PythonChallenge系列-P9 图像绘制

Jan 12, 2014
Coding
PythonChallenge, Python

Connect The Dots #

PythonChallenge系列第九题P9(http://www.pythonchallenge.com/pc/return/good.html,如需登陆:用户名huge,密码file)

页面标题为connect the dots,和图像展示意义一样,就是告诉我们将点连接起来。问题是,点在哪里?

打开网页源码,里面有一个first和一个second,然后提示first+second,意思就是两者的组合能够得到坐标点,+号是什么意思,因为first和second的数字位数并不相等,不能简单的由(first,second)组成一个(x,y)坐标。

那么是不是连接起来?可以尝试。将second连接到first后面,得到一个数字的列表,每两个数字组成一个(x,y)坐标,然后在图像上面将这些坐标点连接起来。

代码 #

#-*- coding: utf-8 -*-

import base64
from urllib.request import Request, urlopen

def downloadContent():
    '''获取网页源代码 需要用户名 密码认证
    从源码中获取 first 和 second,并返回'''

    try:
        url = 'http://www.pythonchallenge.com/pc/return/good.html'
        auth = b'%s:%s' % (b'huge', b'file')
        base64string = base64.encodebytes(auth).decode('utf8').replace('\n', '')
        req = Request(url)
        req.add_header("Authorization", "Basic %s" % base64string)
        src = urlopen(req).read()

        #获取 first 和 second
        import re
        first = re.search(b'first:\n([\d,]+\n)+', src).group().replace(b'first:\n',b'').replace(b'\n',b'')
        second = re.search(b'second:\n([\d,]+\n)+', src).group().replace(b'second:\n',b'').replace(b'\n',b'')
        return (first, second)

    except IOError as e:
        print('downloadContent Error! ', e)
        return ([],[])

if __name__ == '__main__':
    (first,second) = downloadContent()

    list1 = first.split(b',')
    list2 = second.split(b',')

    dot1 = [int(i) for i in list1]#转换成int型
    dot2 = [int(i) for i in list2]#转换成int型

    from PIL import Image,ImageDraw
    img = Image.new('RGB',(500,500),'white')
    imgDraw = ImageDraw.Draw(img)

    imgDraw.polygon(dot1,outline=255)
    imgDraw.polygon(dot2,outline=255)

    img.show()

使用downloadContent函数从网页上读取出first和second的值,并且以一个tuple的形式返回。因为网页需要登陆验证,所以这个函数使用了base64编码和urllib.request.Request的add_header方法。为了从网页中截取出first和second,使用正则表达式re的search方法[re的使用详见Python正则表达式Regex]。利用str.split将first和second分割成列表,然后再转化成int类型的列表dot1、dot2。

使用PIL中的Image模块,new一个空白的RGB图像,然后使用ImageDraw模块的polygon函数,分别传入dot1,dot2,将列表中的int数字,每两个形成一个坐标,绘制出多边形。最后使用show函数显示图像。

解谜 #

图像是一个牛的轮廓。将url中的good替换cow,网页提示

hmm. it’s a male.

那么再试将good替换成bull。OK,成功解谜并打开下一题。

http://www.pythonchallenge.com/pc/return/bull.html

Python知识点 #

1. urllib 实现网页认证 #

利用base64编码一个认证字符串,使用urllib2中的Request请求的add_header方法,将认证信息添加到Request请求中。

try:
    url = 'http://www.pythonchallenge.com/pc/return/good.html'
    base64string = base64.encodebytes(b'%s:%s' % (b'huge', b'file')).decode('utf8').replace('\n', '')
    req = Request(url)
    req.add_header("Authorization", "Basic %s" % base64string)
    src = urlopen(req).read()

except IOError as e:
    print('downloadContent Error! ', e)

2. PIL库中Image和ImageDraw的使用 #

  • Image模块的使用:The Image Module

  • ImageDraw模块的使用:The ImageDraw Module