• English Blog
  • 日本語ブログ

Ian Lewis' Blog

多少の理解、多大の曖昧
  • ホーム
  • About
  • Books
  • Link
  • カレンダー
  • Photo

feedparserで、media コンテンツを取る

2008/11/24 @ 21:12

feedparserで、どうやってビデオを取れるかをずっと悩みましたけど、今日少しだけ、進展した。問題の核心はyoutubeや、vimeoは Yahoo! RSS モジュールを使って、RSS拡張ネームスペースにデータを入れている。この拡張データの処理はfeedparserが中途半端でやってる。見てみよう。

YoutubeのGDATA APIで取ったデータはこうなる

...
<entry>
  <id>http://gdata.youtube.com/feeds/api/videos/R3orQKBxiEg</id>
  <published>2008-07-17T23:58:51.000Z</published>
  <updated>2008-11-24T02:32:25.000Z</updated>
  ...
  <title type="text">Official Watchmen Trailer</title>
  <content type="text">Title speaks for itself

so people don't have to keep answerin
the name of the song is:

smashing pumpkins- the beginning is the end is the beginning</content>
    ...
  <author>
    <name>Garrettheparrot</name>
    <uri>http://gdata.youtube.com/feeds/api/users/garrettheparrot</uri>
  </author>
  <media:group>
    <media:title type="plain">Official Watchmen Trailer</media:title>
    <media:description type="plain">Title speaks for itself

so people don't have to keep answerin
the name of the song is:

smashing pumpkins- the beginning is the end is the beginning</media:description>
    <media:keywords>2009, Comic, Men, Movie, Watch, Watches, Who</media:keywords>
    <yt:duration seconds="140"/>
    <media:category label="Film &amp; Animation" scheme="http://gdata.youtube.com/schemas/2007/categories.cat">Film</media:category>
    <media:content url="http://www.youtube.com/v/R3orQKBxiEg&amp;f=gdata_user_favorites" type="application/x-shockwave-flash" medium="video" isDefault="true" expression="full" duration="140" yt:format="5"/>
    <media:content url="rtsp://rtsp2.youtube.com/CjALENy73wIaJwlIiHGgQCt6RxMYDSANFEgGUhRnZGF0YV91c2VyX2Zhdm9yaXRlcww=/0/0/0/video.3gp" type="video/3gpp" medium="video" expression="full" duration="140" yt:format="1"/>
    <media:content url="rtsp://rtsp2.youtube.com/CjALENy73wIaJwlIiHGgQCt6RxMYESARFEgGUhRnZGF0YV91c2VyX2Zhdm9yaXRlcww=/0/0/0/video.3gp" type="video/3gpp" medium="video" expression="full" duration="140" yt:format="6"/>
    <media:thumbnail url="http://i.ytimg.com/vi/R3orQKBxiEg/2.jpg" height="97" width="130" time="00:01:10"/>
    <media:thumbnail url="http://i.ytimg.com/vi/R3orQKBxiEg/1.jpg" height="97" width="130" time="00:00:35"/>
    <media:thumbnail url="http://i.ytimg.com/vi/R3orQKBxiEg/3.jpg" height="97" width="130" time="00:01:45"/>
    <media:thumbnail url="http://i.ytimg.com/vi/R3orQKBxiEg/0.jpg" height="240" width="320" time="00:01:10"/>
    <media:player url="http://www.youtube.com/watch?v=R3orQKBxiEg"/>
  </media:group>
  ...
</entry>
...

media という名前空間の下に結構データが入ってる。なのに、feedparserはちょっとしか取らない。

>>> d = feedparser.parse("http://gdata.youtube.com/feeds/api/users/IanLewisInJapan/favorites")
>>> e = d['entries'][0]
>>> filter(lambda x: x.startswith('media_'), e.keys())
['media_category', 'media_player', 'media_group', 'media_keywords', 'media_description', 'media_content', 'media_thumbnail']
>>> e['media_content']
u''
>>> e['media_thumbnail']
u''
>>> e['media_player']
u''
>>> e['media_description']
u'Last.fm/presents Yellow Magic Orchestra Interview at Royal Festival Hall in London.\nCheck out http://www.last.fm/Presents to find out about all of our other interviews or upcoming/past events.'
>>>

ビデオのURLはどこかにない。原因はfeedparserの拡張ネームスペース処理に入ってるけども、一言いうと、<media:content>というタグの属性は取れてない。こう見たら、どうやって、とれるかを調べたら、unknown_starttag()というメソッドの中にこのコードを見つけた。

feedparser.py

...
# call special handler (if defined) or default handler
methodname = '_start_' + prefix + suffix
try:
  method = getattr(self, methodname)
  return method(attrsD)
except AttributeError:
  return self.push(prefix + suffix, 1)
...

じゃ、XMLを解析するときに、タグを見つけたら、unknown_starttag()という関数が実行されて、タグの名前に一致するメソッドがあれば、実行する処理やってる。それで、start_media_content()というメソッドがあれば実行してくれるわけだね。でも、どうやって、パーサークラスに付けるのか。feedparserは_StrictFeedParserというクラスを名前で使ってるから、自分が作ったクラスを_ScrictFeedParserと交換。

feedparser._StrictFeedParser_old = feedparser._StrictFeedParser
class DlifeFeedParser(feedparser._StrictFeedParser_old):
 
  def _start_media_content(self, attrsD):
    self.entries[-1]['media_content_attrs'] = copy.deepcopy(attrsD)
feedparser._StrictFeedParser = DlifeFeedParser

それで、またparse()を実行すると、

>>> import feedparser
>>> import copy
>>> feedparser._StrictFeedParser_old = feedparser._StrictFeedParser
>>> class DlifeFeedParser(feedparser._StrictFeedParser_old):
...      
...   def _start_media_content(self, attrsD):
...         self.entries[-1]['media_content_attrs'] = copy.deepcopy(attrsD)
...     return self.push('media_content', 1)
...
>>> feedparser._StrictFeedParser = DlifeFeedParser
>>> d = feedparser.parse("http://gdata.youtube.com/feeds/api/users/IanLewisInJapan/favorites")
>>> filter(lambda x: x.startswith("media_"), d['entries'][0].keys())
['media_category', 'media_player', 'media_group', 'media_content_attrs', 'media_keywords', 'media_description', 'media_content', 'media_thumbnail']
>>> d['entries'][0]['media_content_attrs']
['medium', 'format', 'url', 'expression', 'duration', 'type', 'yt:format']

それで、media:contentの属性を取れた。 media:groupの下にcontentが複数ある場合もあるから、もうちょっとまとめないといけないけど、やり方が少し分かってきた。

フィードバックを送る
  タグ: atom, feedparser, Media, Python, rss

Django サイトマップ フレームワーク

2008/11/18 @ 21:51

Django sitemap frameworkを使うのが簡単過ぎる。下記のようにサイトマップクラスを作って、urls.pyに登録するだけ。サイトマップに載るURLを取るのに、サイトマップフレームワークが自分が作ったクラスのitems()を呼び出して、アイテムのget_absolute_url()を順番に呼び出す感じ。

models.py

from django.db import models
...
class Entry(models.Model):
...
    @permalink
    def get_absolute_url(self):
        return ...
...

sitemap.py

from django.contrib.sitemaps import Sitemap
from mysite.blog.models import Entry

from django.contrib.sitemaps import Sitemap
from mysite.blog.models import Entry

class BlogSitemap(Sitemap):
    priority = 0.5

    def items(self):
        return Entry.objects.filter(is_draft=False)

    def lastmod(self, obj):
        return obj.pub_date

    # changefreq can be callable too
    def changefreq(self, obj):
        return "daily" if obj.comments_open() else "never"

urls.py

from mysite.blog.sitemap import BlogSitemap
...
sitemaps = {
    "blog": BlogSitemap
}
(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
...

サイトマップインデクスも作れる。GoogleのURL 50,000件の制限があるため、サイトマップをPagenatorで自動的にURLを振り分けてくれる。urls.pyをこう変えるだけ

from mysite.blog.sitemap import BlogSitemap
...
sitemaps = {
    "blog": BlogSitemap
}
(r'^sitemap.xml$', 'django.contrib.sitemaps.views.index', {'sitemaps': sitemaps}),
(r'^sitemap-(?P&amp;amp;lt;section&amp;amp;gt;.+)\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps':sitemaps})
...

素敵だな。

後、サイトのコンテンツが変更された時、Googleが新しいコンテンツをインデクスするために ping_googleというmanage.pyコマンドが用意してある。

python manage.py ping_google

でも、他の検索エンジンが同じようなサービスがあるのに、ping_googleしかないので、上記のようなコマンドをいくつも作っていた。

フィードバックを送る
  タグ: django, Google, Python, sitemap

DjangoGraphviz

2008/11/08 @ 11:40

今日、Djangoアプリケーションのモデルの構成を分かりやすく見たくて、モデル構成からGraphviz ドットファイルを生成できれば、いいなと思って、DjangoGraphvizを見つけた。ただ、ここからダウンロードして、こう実行する。

PYTHONPATH=$PYTHONPATH:. DJANGO_SETTINGS_MODULE=appmodule.settings python modelviz.py applabel > app.dot
dot app.dot -Tpng app.png

最近作った dlifeのモデル構成イメージを作るとこれがでる。

よくできてるね。

フィードバックを送る
  タグ: django, graphviz, model, Python

初出勤日

2008/11/04 @ 21:57

新しい会社に入って、初出勤日が無事に終了しました。結構いい感じでした。前の会社では、狭いとこに住み、残業してたりしてて、電車が込んでて、二年間結構苦しんで仕事してたんです。今はもう広いマンションで住んでて、会社の人がゆっくりで仕事してて、電車も空いてて、PythonとDjangoで仕事できて、すごく夢の仕事みたい。

緊張してて、日本語の間違えとかしてて、お昼のレストランから帰ろうとして、靴をはいたときに不器用だったんですけど、みんな、いろな質問をしてくれたりして、思ったより僕のことを迎えてくれてうれしかった。これからも、頑張っていきたいと思います。

フィードバックを送る
  タグ: お仕事

Python温泉

2008/10/27 @ 16:31

先週末、  Python温泉第4回に行ってきました。Python温泉は金土日なんですけど、前回と同じく土日、1泊にやってきました。今回は集中できたけど、前回より友達つくりや、会話ができてなかったという感覚だった。いろいろ寂しかった。でも、ビープラウドのid:tokibitoさんと、jQuery Internalsのdata()関数の実装や、feedparserや, Djangoの話をして、少し仲良くなった。ブログに俺について何も書いてくれなかったけど ^^;

Python温泉参加者のブログにまとめ(id:voluntasのまとめ, id:tokibitoのまとめ)が多いから、

まとめ:

  • すぐ転職がばれた
  • FriendFeedや、sweetcronみたいなlifestreamをdjangoで頑張って作った。(dlife)
  • 温泉一人で入って寂しかった。
  • id:tokibitoさんにjQuery Internalsのdata()関数を紹介
  • いつも土日で来るから、自己紹介に出ないので、誰が誰か分からなくなっちゃう ( 俺のせい? )
  • feedparserを分かりやすくすぐ使えるから感動。しかし、写真、ビデオの処理悩み中
  • ブログを見てくれて、リンクする人が以外に少ない。( 何も書いてないからかな?^^; )
  • 夕食の時間の抽選で、アクセンス・テクノロジーの増田さん(id:whosaysni)から、Python シャツを頂きました!!
  • 駅から、一人で帰って寂しかった。


フィードバックを送る
  タグ: django, lifestream, Python, python温泉

ウェブホスティング移動

2008/10/13 @ 13:02

最近PythonやDjangoの開発をだんだんやっていてる僕が、このサイトを新しいウェブホスティングプロバイダーに移動することにした。 今は Haswebという安いプロバイダーなんですけど、Pythonにあまり相性がよくないので、Pythonアプリをサーバーに動かすのが難しすぎる。 簡単なPython cgiを対応してるだけで、コンパイルもできないから、Pure Pythonライブラリしかインストールできない。 なので、PylonsがおすすめしてるWebfactionに移動することにした。 Django,Pylonsに結構やさしくて、ライブラリをコンパイルできるから、使いやすいと思ってる。 それで、このサイトでいろいろなPythonウェブアプリをだんだん作っていきたいと思ってる。

Send feedback
  Tags: django, hasweb, Pylons, Python, webfaction, ホスティング
1 2 3 4 5 6 7 8 9 10 11 ... 15 >>
  • タグ

    appengine datatel django general google googleマップ japan meetup nintendo nintendo ds pylons python sitemap ubuntu windows お正月 イベント インターネット ウェブサイト開発 エミリー オープンソース ゲーム コンピュータ ソフトウエア開発 ソートス ピザ モバイル リナックス 乾燥機 交通情報 京都 仕事 入国 写真 出張 夏 大阪 新幹線 旅行 日本 日本語 日本語能力試験 東京 残業 玲子ちゃん 相撲 箱根 紅葉 花見 葬式

  • XML フィード

    • RSS 2.0: 投稿, コメント
    • Atom: 投稿, コメント
    What is RSS?
  • 検索




  • 画像をランダムに


    Warning: Division by zero in /home/ianlewis/webapps/gallery2/modules/core/classes/GalleryUtilities.class on line 485
    The Statue of Liberty

    The Statue of Liberty

  • last.fm Flickr Live Journal del.icio.us Yahoo Amazon Facebook Sourceforge Notebook Twitter LinkedIn! Meetup!

powered by b2evolution free blog software


Contact | Powered by b2evolution
Credits: Foppe Hemminga | blog software | web hosting | monetizing