肥嘟嘟(Fatbobman)的学习笔记Rss Feed

上学的时候懒不愿意做笔记,但确实了解笔记的重要性。现在想做笔记了,但是还是懒,当然对于重要性的认识丝毫没有动摇。

2020/05/28

十几年后重开博客

重新创建了博客。

2005/12/05

python 的 urllib 如何处理gzip的页面数据

    python-cn上一个朋友提出的问题,自己以前也没想过,恰巧django中有一个middleware是做gzip处理的,看了一下它的代码,了解到可以通过StringIO的方式,将字符串以文件的形式来进行处理。
StringIO应该是一个非常有用的模块,因为很多函数都是只支持文件的,使用它后就没有问题了。


import urllib2
import cStringIO
import gzip

f=urllib2.urlopen('http://www.gzip.com/aaaxxx
') #gzip url
zbuf=cStringIO.String(f.read())
print gzip.GzipFile(fileobj=zbuf,mode='rb').read()


--
我的blog: http://www.donews.net/fatbobman

2005/12/02

幸福的时光是短暂的?

从昨天夜里开始,我又无法通过正常途径访问我在blogger上的blog了。我不知道该用悲哀还是什么其他的情绪来看待这个现象。
ok,恢复我在donews上的blog,不过继续保留通过gmail向这里发blog,或许、说不定、可能、但可是在某年某月的某一天,GFW又伸出它那仁慈的臂膀,将blogger推向我的怀抱呢:)

2005/12/01

python challenge 又解过两关

花了2天时间终于过了第12关。呵呵,感觉到里面提供的很多线索其实是一种误导,需要认真、认真、再认真才可以呀。
时间有点晚了,明天再总结一下解题的思路吧。
打算从11题起,不将谜底直接说出来了,保留悬念。python challenge真是好玩呀:)再称赞一下!

2005/11/29

Python Challenge 答案 (6-10)

[http://www.pythonchallenge.com/]

The Python Challenge

第6题: zip 模块
title提示是一对。
源代码中出现〈!-- 〈-- zip --〉字样
从http://www.pythonchallenge.com/pc/def/channel.zip 下载zip文件
(提示够变态吧)
打开zip文件中的readme.txt 可以看到
welcome to my zipped list.

hint1: start from 90052
hint2: answer is inside the zip
感觉解题思路基本上和上面那个反复调用url的题一样
r=re.compile(r'(\d+)$')
nextnothing='90052'

while(1):
try:
f=open('./python challenge/%s.txt' % nextnothing)
result=f.read()
f.close()
print result
oldnextnothing=nextnothing
nextnothing=r.search(result).group()
except:
break

执行后最后显示
collect the comments

有点昏吧,哪里来的comments。其实就在zip文件里。这道题最后还是需要用zip模块来完成
import re
r=re.compile(r'(\d+)$')

import zipfile
comment=[]
nextnothing='90052'
f=zipfile.ZipFile('./python challenge/channel.zip')
while(1):
try:
comment.append(f.getinfo('%s.txt' % nextnothing).comment)
nextnothing=r.search(f.read('%s.txt' % nextnothing)).group()
except:
print ''.join(comment)
break

运行屏幕显示一个由字符组成的图片,可以看出图案是HOCKEY
进入http://www.pythonchallenge.com/pc/def/hockey.html
什么?还没结束!
上面显示it's in the air. look at the letters.
此时,再次注意观察前面出现的hockey图片发现,每个字母的图案都是由一个单独的字母组成,得到最终答案oxygey
下题入口http://www.pythonchallenge.com/pc/def/oxygen.html

第7题: pil出场。颜色拾取
屏幕上显示一幅图,图片的中间部分是由规律的灰度块组成。猜测信息应该是由这些灰度提供。
通过gimp进一步分析可获得整个区域灰度块长度为608,除第一小块外,其他间隔都是7个象素点。也就是说每隔7个点可以获得一个颜色数据。由于图片是彩色的(RGBA模式),而只有灰度的颜色数据应该是255级以内,推测可能会是ascii。

import Image
im = Image.open('./python challenge/oxygen.png')
ilist = im.convert('L').getdata() #将色彩转换为灰度,这样只获得一个值
result=[]
for i in range(0,608,7):
result.append(chr(ilist[im.size[0]*50+i]))
print ''.join(result)

果然,运行程序显示:smart guy, you made it. the next level is [105, 110, 116,
101, 103, 114, 105, 116, 121]
再次处理可得到答案
hint=[105, 110, 116, 101, 103, 114, 105, 116, 121]
answer=[]
for c in hint:
answer.append(chr(c))
print ''.join(answer)

最终答案:integrity
下题入口:http://www.pythonchallenge.com/pc/def/integrity.html

第8题:bz2解码
屏幕显示一个蜜蜂图片。查看页面源代码可以看到里面提示有加过密的用户名、密码。
点击蜜蜂可进入一个需要输入口令的页面,说明此题应该就是解开用户名、密码
说实话,这道题我始终没有找到破解加密算法的思路,直到看到网上有人说google以下BZh91AY。这个字符串时用户名和密码最开始相同的部分。google后可以看到介绍python
bz2模块,得到解题思路。
import bz2

un = 'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00
\x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
pw = 'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$
\x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'

un=bz2.decompress(un)
pw=bz2.decompress(pw)

print un
print pw

运行得到答案
huge
file
登录即可进入下题

下题入口http://www.pythonchallenge.com/pc/return/good.html

第9题:pil再度出马,描点
屏幕上显示一幅风景画,上面有很多小黑点。
title提示,连接点
page source中可以看到两组数据 first second 并提示 first+second=?
起初我真的在gimp上把图片上面的点用画笔描了起来,看看是否有什么提示,不过一无所获。
后来观察first和second的数据,发现其值均在该图片的x,y size之内,并且两组数据的个数都为偶数,获得灵感是否是坐标数据
import Image
first=[
146,399,163,403,170,393,... snip]
second=[
156,141,165,135,169,...snip]
im=Image.open('./python challenge/good.jpg')
f=[]
for i in range(0,len(first),2):
f.append((first[i],first[i+1]))
print f
for xy in f:
im.putpixel(xy,(255,0,0))

f=[]
for i in range(0,len(second),2):
f.append((second[i],second[i+1]))
print f
for xy in f:
im.putpixel(xy,(255,0,0))
im.show()

呵呵,可以隐约在图片上面由红色的点组成了一头牛的图案。
first是外缘轮廓,second是头的轮廓
赶紧进入http://www.pythonchallenge.com/pc/return/cow.html
结果发现提示hmm. it's a male.
唉,分得还挺细。。
得到最后结果:bull

下题入口:http://www.pythonchallenge.com/pc/return/bull.html

第10题: 数字列表
屏幕下方提示 :len(a[30]) = ?
点击图片可获得数据:
a = [1, 11, 21, 1211, 111221,
知道应该是根据这个提示找出规律,扩充列表获得答案。
不过规律何在?解此题。。。。耗时超过2小时。。。。主要是笨呀。
最后终于明白值之间的规律。就是每个值都是对前一个值得文字描述。
什么?文字描述,不错,念起来就知道了
比如说第一个是 1
第二个就是 1个1 (11)
第三个就是 2个1 (21)
第4个就是 1个2 1个1 (1211)
第5个就使 1个1 1个2 2个1 (111221)
一次类推。。。。说实话,开始总是想数字之间是否有什么数学运算上的关系,所以总也推算不出。

olda = [1, 11, 21, 1211, 111221]

def _index(c,list):
for i in range(len(list)):
if list[i]!=c:
return i
return -1

while len(olda)<31:
result=''
resultlist=[]
a=str(olda[-1])
while len(a)>0:
firstdiffindex = _index(a[0],a[1:])
if firstdiffindex==-1:
resultlist.append(a)
break
else:
resultlist.append(a[0:firstdiffindex+1])
a=a[firstdiffindex+1:]
for l in resultlist:
result +=str(len(l))+str(l[0])

olda.append(int(result))

print len(str(olda[30]))

得到答案:5808
下题入口:http://www.pythonchallenge.com/pc/return/5808.html

--
Posted by fatbobman to 肥嘟嘟的闲言碎语 at 11/29/2005 01:58:15 下午

Django 提供了非关键字的url map方式

http://www.djangoproject.com/documentation/url_dispatch

from django.conf.urls.defaults import *

urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)

由于没有关键字,因此所获得的参数是按顺序调用
类似:news.views.month_archive(request, '2005', '03')
个人所好不同吧。总之django一直在努力!

2005/11/28

Python Challenge 答案 (1-5)

The Python Challenge
从没想过解题还能这么有趣。
刚打开pythonchallenge的站点时有点莫名其妙的感觉,并不清楚到底问题在哪里。后来发现其中的奥秘就是你要在他所给的线索中找到下一题的url,这样便可以进入下一关了。
python challenge中有几个地方是重要的线索来源:
1:title (其中通常含有解题的思路提示)
2:page source (页面源代码,中间通常有数据资源,或者指明数据资源的位置)

第0题:
出现一幅画面,上面写着2**38,教你如何进入下一关。
计算出2**38 =
将浏览器中的 http://www.pythonchallenge.com/pc/def/0.html 改成 http://www.pythonchallenge.com/pc/def/274877906944.html 即可

第1题:密码转换
图片中显示出字符转换的规律 new_c=chr(ord(old_c)+2) 超过自动回转
title中提示making trans
因此比较简单的方法是直接使用string.translate进行转换。
oldstr = ' ...' #屏幕上显示的加密数据
import string
old='abcdefghijklmnopqrstuvwxyz'
new='cdefghijklmnopqrstuvwxyzab'
print string.translate(oldstr,string.maketrans(old,new))

得到如下显示:
i hope you didnt translate it by hand. thats what computers are for.
doing it in by hand is inefficient and that's why this text is so long.
using string.maketrans() is recommended. now apply on the url.

然后再对url http://www.pythonchallenge.com/pc/def/map.html上面的 map 进行一次转换得到ocr.
下一题入口:
http://www.pythonchallenge.com/pc/def/ocr.html

ps:说实话如果不是做这题,我可能跟不不会想起用maketrans这类的函数。

第2题: 抽取字符
页面显示提示数据在page source中
查看页面源代码。可以看到一组混乱的数据,并得到如下提示:find rare characters in the mess below:
最初我解此题时是将数据中所有出现的字符都放入哈希并计算出现的次数,后来发现只有英文字母是之出现一次的,由于哈希没有顺序,猜结果耗费的不少时间,后来干脆只提取字符一下子就获得的最后的结果。

#chardict={}
#for c in ocrstr:
# if chardict.has_key(c) :
# chardict[c]+=1
# else:
# chardict[c]=0
#
#print chardict

print ''.join([c for c in ocrstr if c.isalpha()])

计算后得到答案:equality
下题入口:http://www.pythonchallenge.com/pc/def/equality.html

第3题: 提取字符
title中提示使用正则
页面显示 两侧被3个(且只为3个)大写字母包围的小写字母
page source中有待处理的数据

import re
result=re.findall(r'[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]',sourcestr)
print ''.join(result)

得到答案 linkedlist。
进入http://www.pythonchallenge.com/pc/def/linkedlist.html后显示linkedlist.php
下题入口 http://www.pythonchallenge.com/pc/def/linkedlist.php

ps:不是python解题吗,怎么用php:)

第4题:变态的url刷新
从title和图片可以看出来这题就像打水井一样,需要一遍又一遍的机械进行才能获得答案。
page source显示 图片的href 后面有一个nothing=12345的调用
urllib may help. don't try ALL nothings, since it will never
end. ~300 times is enough.
调用linkedlist.php?nothing=12345得到了and the next nothing is 92512 从中得到规律,根据每次获得的nothing值来进行下次url访问。

import urllib2
import re
r=re.compile(r'(\d+)$')
nextnothing='12345'
i=0
while(1):
try:
f=urllib2.urlopen('http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s'% nextnothing)
result=f.read()
f.close()
print result
oldnextnothing=nextnothing
nextnothing=r.search(result).group()
i+=1
except:
nextnothing=oldnextnothing

需要提示的是,这题竟然在访问的过程中还有变化。在进行了漫长的调用后当nothing 为92118,会显示Yes. Divide by two and keep going。中断程序,将nothing设置为 46059 继续运行。获得最后结果 peak.html
下题入口:http://www.pythonchallenge.com/pc/def/peak.html

第5题:pickle应用
说实在的尽管页面提示我将 peak hell 读出声来,我还是没有意识到pickle这个词(英文都还给了党)。
source page中有如下显示
查看http://www.pythonchallenge.com/pc/def/banner.p,通过显示的数据才反应过来应该是pickle

import urllib2
import cPickle as pickle
f=urllib2.urlopen('http://www.pythonchallenge.com/pc/def/banner.p')
result=pickle.Unpickler(f).load()

result是一个多维列表。分析数据感觉应该是一个字符组成的图画描述。
line=''
for n in result:
for m in n:
line+= m[0]*m[1]
print line+'\n'
line=''

打印后可获得答案channel
下题入口:http://www.pythonchallenge.com/pc/def/channel.html



python challenge目前共有33题,通过做这些题不仅可以开阔思路,更可以强迫自己去使用可能很少会使用的一些python模块,让自己在实践中提高。

道语言最新版本0.9.6beta发布

Google 网上论坛 : cn.bbs.comp.lang.python: "道语言最新版本0.9.6beta发布"
刚才在论坛里看见的。
简单的看了一下文档,感觉很不错。国人的作品!支持一下!
作者傅利民简介

2005/11/27

Django 支持静态文件的web服务了(续)

Django | Documentation | How to serve static files
试用了一下,很好用.
mime支持是用python自带的 mimetypes模块
mimetype = mimetypes.guess_type(fullpath)[0]
另外可以通过设置
show_indexes=True 来显示目录结构
(r'^site_media/(?P.*)','django.views.static.serve',{'document_root':'d:/myscripts/rssforward/media','show_indexes':True}),

各个静态文档之间的嵌套也完美的支持了。

呵呵,又解决了一个问题。本来我还打算用middleware做一个呢。结果django自己在view层支持了,省了不少心。

Django 支持静态文件的web服务了

http://www.djangoproject.com/documentation/static_files/
尽管django仅仅是推荐在debug方式下使用,不过还是增添了很大的便利性。对于小型的应用终于可以不需要第三方web server参与了。
不过还不知道对于各种文件类型的meta支持如何。明天测试一下。

2005/11/23

Django admin 下藏有乾坤

标题有点夸大,不过django中确实有很多undocument的东西有趣又有用。
随便翻看了一下django的代码,看到了不少不知道的好东西。比如 /admin/doc
这个文档中包含了整个项目所有model的详细说明(自动生成的)。
又比如django自己内部的url配置中还使用通过判断某个模块安装与否来动态添加url map,这些都是目前文档没有提到的。
应该说以django的强大功能来衡量,目前的文档资料还是很匮乏的,不过开源项目就是有这个优势,我们可以通过阅读源代码来学习,一方面补充资料的不足,另一方面可以更好的理解系统的原理。
学海无涯呀。

2005/11/22

newedit 发布3.1并支持django wizard及model定义

http://blog.donews.com/limodou/archive/2005/11/22/635273.aspx
newedit 发布了3.1。并增加了交互式的django定义model功能。效果很好,不过暂时还不支持META 的定义。
newedit确实越来越好了,打算今后大部分的python开发都在这上面来完成。

2005/11/18

如何判断rss feed内容是否更新

为了熟悉django,打算照rssfwd.com的模式制作一个类似的项目。
在判断rss feed内容是否有更新上,我遇到了一点麻烦。我在python下使用feedparser.py来解析各种格式的rss或者atom等信息,结果发现很多站点提供的信息里面没有updated或者modified等时间信息。etag也是没有几个站点支持。这样造成了我的困惑,对于没有时间信息的rss资源如何判断是否更新过呢?
好在rssfwd是开源的,看了一下它的ruby程序。虽然不懂ruby,但大概上还是能看明白的。我发现rssfwd采用通过将每个feed里content
hash后的数据保存在catch中的方法来判断是否有变化。这确实不是一个很好的方法(效率低、占用存储空间大、无论是否更改都再度占用带宽下载),不过这是一个非常有效地解决手段。一下子将程序中需要考虑的众多针对各种版本rss/atom等资源兼容性问题就巧妙解决了。