[Level 17]
Title: eat?
圖片就是提示了。餅干是cookies,cookie不僅僅是餅干。瀏覽器查看網頁cookie,顯示you+should+have+followed+busynothing...。busynothing,nothing,且左下角的圖是第四關的圖。從busynothing=12345
開始,收集cookie中的info值。
import httplib2,re
h = httplib2.Http('.Cache')
url, num = 'http://www.pythonchallenge.com/pc/def/linkedlist.php?busynothing=', '12345'
pattern = re.compile('info=(.*)')
info = ''
while num.isdigit():
resp,content=h.request(url+num)
info += pattern.search(resp['set-cookie'].split(';')[0]).groups()[0]
num = content.decode('utf-8').split(' ')[-1]
print(info)
info最終是一段以BZh91AY
開頭的字符串,使用bz2解壓,異常終止,顯示OSError: Invalid data stream。搜了下,這段字符需要轉換:
import bz2,urllib.parse
info = urllib.parse.unquote_to_bytes(info.replace('+','%20'))
print(bz2.decompress(info).decode('utf-8'))#ascii
得到這么一段信息:
is it the 26th already? call his father and inform him that "the flowers are on their way". he'll understand.
his father指的是十五關莫扎特的父親Leopold Mozart,call?phone,十三關的phone:
import xmlrpc.client
xmlrpc = xmlrpc.client.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php')
print(xmlrpc.phone('Leopold'))
得到555-VIOLIN。然而VIOLIN.html不存在,violin.html顯示no! i mean yes! but ../stuff/violin.php.。violin.php顯示一張照片,標題是it's me. what do you want?。前面提示inform him that "the flowers are on their way",怎樣inform?卡了下,是要把網頁cookie中的info值設置為the flowers are on their way。
url = 'http://www.pythonchallenge.com/pc/stuff/violin.php'
headers = {'Cookie':'info=the flowers are on their way'}
print(h.request(url,headers=headers)[1].decode('utf-8'))
得到oh well, don't you dare to forget the balloons.,嗯,[Level 18]
小結
- 使用httplib2庫,cookie信息包含在
httplib2.Http().request()
返回的Response
實例中。 - 直接遍歷得到的最終info值需要轉義,使用
urllib.parse.unquote()
或urllib.parse.unquote_plus()
方法返回的二進制對象均不能正常使用bz2解壓。若要使用該方法,需要額外的參數:urllib.parse.unquote_plus(info,'latin1').encode('latin1')
- 經
urllib.parse.unquote_to_bytes(string)
方法轉換返回的對象可以正常解壓,該方法功能是將%xx
轉義替換為其等效的single-octet字符(unquote_plus()
和unquote()
是單個字符),以字節對象返回。不像unquote_plus()
能將+
轉為空格,unquote_to_bytes()
需要手動替換。urllib庫中文文檔可參考Urllib庫 - 使用
Http.request()
設置cookie,cookie包含在headers中。headers={'Cookie': 'cookie_value'}
Python Challenge Wiki
1. 使用urllib庫獲取cookie信息。
import urllib.request
h = urllib.request.urlopen(url)
cookie = h.getheader('Set-Cookie')
或直接獲取info值:
from urllib.request import build_opener,HTTPCookieProcessor,HTTPHandler
import http.cookiejar
cj = http.cookiejar.CookieJar()
opener = build_opener(HTTPCookieProcessor(cj),HTTPHandler)
f = opener.open(url)
for cookie in cj:
print(cookie.value)
2. 設置cookie。
from urllib.request import Request, urlopen
from urllib.parse import quote_plus
req = Request(url, headers = { "Cookie": "info=" + quote_plus(msg)})
#print(urlopen(req).read().decode())
或者這樣:
import urllib.request, urllib.parse
o = urllib.request.build_opener()
o.addheaders.append(('Cookie', 'info='+urllib.parse.quote_plus(msg)))
res = o.open(url)
#print(res.read().decode())