PythonChallenge系列-P9 图像绘制

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

P9.jpg

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

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

p91.jpg

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

代码

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

import urllib2,base64

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

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

        #获取 first 和 second
        import re
        p1 = re.compile('first:\n([\d,]+\n)+')
        p2 = re.compile('second:\n([\d,]+\n)+')

        first_rst = re.search(p1,src)
        second_rst = re.search(p2,src)
        first=''
        second=''
        if first_rst!=None:
            #print first_rst
            first = first_rst.group().replace('first:\n','').replace('\n','')
            #print first
        if second_rst!=None:
            #print second_rst
            second = second_rst.group().replace('second:\n','').replace('\n','')
            #print second

    except IOError, e:
        print 'downloadContent Error! ', e
        return (first,second)
    else:
        return (first,second)

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

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

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

    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编码和urllib2.Request的add_header方法[urllib2模块使用详见Python中如何使用urllib2模块]。为了从网页中截取出first和second,使用正则表达式re的search方法[re的使用详见Python正则表达式Regex]。利用str.split将first和second分割成列表,然后再转化成int类型的列表dot1、dot2。

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

p92.jpg

解谜

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

hmm. it’s a male.

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

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

Python知识点

1. urllib2 实现网页认证

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

import urllib2,base64
try:
    url = 'http://www.pythonchallenge.com/pc/return/good.html'
    req = urllib2.Request(url)

    base64string = base64.encodestring('%s:%s' % ('yourname', 'yourpassword')).replace('\n', '')
    req.add_header("Authorization", "Basic %s" % base64string)

    response = urllib2.urlopen(req)
    html = response.read()
    print html

except IOError, e:
    print 'Error! ', e

2. PIL库中Image和ImageDraw的使用

Image模块的使用:The Image Module

ImageDraw模块的使用:The ImageDraw Module

作者:JarvisChu
原文链接:PythonChallenge系列-P9 图像绘制
版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0

发表评论