3266855 ランダム
 HOME | DIARY | PROFILE 【フォローする】 【ログイン】

傀儡師の館.Python

傀儡師の館.Python

【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! --/--
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x

PR

Recent Posts

Calendar

Keyword Search

▼キーワード検索

Category

Archives

2023.11
2023.10
2023.09
2023.08
2023.07

Freepage List

Profile

kugutsushi

kugutsushi

Free Space

設定されていません。
2008.04.22
XML
カテゴリ:IronPython
『IronPythonの世界』を読む (8) の続き。Part 5 の「インターネットにアクセスする」P.305 あたりを読む。


IronPythonの世界

urllib は socket ライブラリの互換性の問題があるので、.NET Framework の System.Net サービスを使った例が載っている。

とりあえず、このあたり見ながら簡単に試してみる。

import clr
clr.AddReference("System")
from System import *
from System.Net import *

url = Uri("http://pypi.python.org/pypi?:action=rss")
filename = "pypy.rss"

client = WebClient()
client.DownloadFile(url, filename)

とかすると、ダウロードできるようだ。urlparse の代わりには、Segments を使うと、

>>> url = Uri("http://www.example.org/test.html")
>>> url.Segments
System.String[]('/', 'test.html')
>>> url.Segments.Length
2
>>> url.Segments[url.Segments.Length -1]
'test.html'

のように URL をパースできる。

urllib で文字列として読み込んでとかやろうとすると、

import urllib

f = urllib.urlopen("http://pypi.python.org/pypi?:action=rss")
print f.read()

とかなるが、これを IronPython でやろうとすると、

import clr
clr.AddReference("System")
from System.Text import *
from System import *
from System.Net import *

client = WebClient()

# 読み込むときのエンコーディングを指定したければ、
# System.Text.Encoding を使って、こうできる。
cleint.Encoding = Encoding.GetEncoding("utf-8")

print client.DownloadString("http://pypi.python.org/pypi?:action=rss")

バイナリデータの場合は、DownloadData を使えばよいらしい。

プロキシの指定はどうするのかなぁ。urllib を使うなら FancyURLopener が使える。

import urllib

proxies = {'http': 'http://proxy.example.com:3128/'}
opener = urllib.FancyURLopener(proxies)
f = opener.open("http://www.python.org")
f.read()

IronPython の場合は、

clr.AddReference("System")
from System import *
from System.Net import *

client = WebClient()
client.Proxy = System.Net.WebProxy('http://proxy.example.com:3128')

print client.DownloadString("http://pypi.python.org/pypi?:action=rss")

とかすればよいのかな。

書籍には、System.Net.Proxy と書いてあるけど、dir(System.Net) で見てみると、そんなものはなくて、WebProxy しかないから、そうしてみた。BypassOnLocal だと、ローカルの場合はプロキシーをバイパスとか Internet Explorer のオプションで指定しているのと同じような感じでいけるようだ。

>>> print client.Proxy.__doc__
WebProxy()
WebProxy(Uri Address)
WebProxy(Uri Address, bool BypassOnLocal)
WebProxy(Uri Address, bool BypassOnLocal, Array[str] BypassList)
WebProxy(Uri Address, bool BypassOnLocal, Array[str] BypassList,
ICredentials Credentials)
WebProxy(str Host, int Port)
WebProxy(str Address)
WebProxy(str Address, bool BypassOnLocal)
WebProxy(str Address, bool BypassOnLocal, Array[str] BypassList)
WebProxy(str Address, bool BypassOnLocal, Array[str] BypassList,
ICredentials Credentials)

アップロードのときには、UploadString や UploadFile とかを使う例がある。ただし、urllib.urlencode 相当のものはないらしく、urllib.urlencode を使った例になっている。ところが、

urllibモジュールのurlencode メソッドにユニコード文字列(日本語を含む)が含まれると、エラーになります。この現象は、IronPythonでCPython の urllib を使用すると発生します。

とある。んー、困ったなと試してみる。


>>> import sys
>>> sys.path.append("C:\\Python24\\lib")
>>> import urllib
>>> a = "傀儡師の館"
>>> d = {"name":a.encode("utf-8")}
>>> urllib.urlencode(d)
Traceback (most recent call last):
File , line 0, in <stdin>##85
File C:\Python24\lib\urllib.py, line 1168, in urlencode
File mscorlib, line unknown, in GetString
File mscorlib, line unknown, in GetString
File mscorlib, line unknown, in CreateStringFromEncoding
File mscorlib, line unknown, in GetCharCount
File mscorlib, line unknown, in InternalFallback
File mscorlib, line unknown, in Fallback
File mscorlib, line unknown, in Throw
UnicodeDecodeError: インデックス 0 にあるバイト [E5] を指定された
コード ページから Unicode へ変換できません。

なるほど、確かにエラーになる。うざったいので、とりあえず、urllib の中を見る。str() を使っているところがエラーの原因なので、

import sys
if sys.platform == 'cli':
def str(s):
return s

と入れちゃう。そうすると、

>>> urllib.urlencode(d)
'name=%E5%82%80%E5%84%A1%E5%B8%AB%E3%81%AE%E9%A4%A8'

となる。

あるいは、

def urlencode(query):
""" ちょっとインチキ版 """"
query = query.items()
l = []
for k, v in query:
k = urllib.quote_plus(k)
v = urllib.quote_plus(v)
l.append(k + '=' + v)
return '&'.join(l)

import sys
sys.path.append("C:\\Python24\\lib")
import urllib

urllib.urlencode = urlencode
a = "傀儡師の館"
d = {"name":a.encode("utf-8")}
print urllib.urlencode(d)

.NET 的にやると、

import clr
clr.AddReference("System.Web")
import Web.HttpUtility

def urlencode(query):
query = query.items()
l = []
for k, v in query:
k = HttpUtility.UrlEncode(k)
v = HttpUtility.UrlEncode(v)
l.append(k + '=' + v)
return '&'.join(l)

この場合、渡すのはユニコード文字列のままでいい。'name=%e5%82%80%e5%84%a1%e5%b8%ab%e3%81%ae%e9%a4%a8' が返ってくる。

まあ、なんとかしのげないことはないって感じかな。でも、やっぱり、CPython は使えるけど .NET はよく分からないという人にとっては、かなり躓きどころが多い。けれども、.NET がよく分かっている人にとってみたら、Python のインタラクティブ性と .NET の力で、かなり便利に使えるだろうって、改めて思う。

IronPython を使っていると Python の構文は使っているけど、どんどん中身が .NET Framework になっていく。なるほど、これぞマイクロソフトの意図するところなんだな。プログラミングしようとすると、.NET Framework を調べざるを得なくなる。そうしていると徐々にその道に馴染んでいってしまう。


なかのひと





お気に入りの記事を「いいね!」で応援しよう

Last updated  2008.04.23 04:15:24
コメント(0) | コメントを書く
[IronPython] カテゴリの最新記事



© Rakuten Group, Inc.