Hatena::ブログ(Diary)

風柳メモ このページをアンテナに追加 RSSフィード Twitter

2009-04-04

Feedパレット:任意のサイトのフィードパターンを作成・共用できるサービスを公開

Feedパレットって?

BSXPath.pyを作りっぱなしというのもなんなので…ありがち*1ではありますが、任意のサイトのFeedを作成出来るサービスを試作してみました。

任意のサイトのフィードパターンを作成・共用できるサービス

f:id:furyu-tei:20090405052050p:image

▼どんなサービス?

Feed配信されていないサイトについて、だれかが一度Feedパターン(パレット)を作成して登録しておけば(登録にはGoogle アカウントが必要)、あとは誰でもそのパレットを利用して当該サイトのFeedを購読できる(購読だけならアカウントは不要)、というものです。


『他人のブログの記事にコメントをつけたんで、しばらくその記事のコメント欄を監視していたい』といったニッチな要求にも対応可能です(笑)→


▼特徴

一応、特徴としては以下のようなものがあります。

  1. Google アカウントを持っていれば、Feedパターン(パレット)を自分で追加可能
  2. 他の人が作ったFeedパターン(パレット)を共用してFeed購読
  3. Feedパターン(パレット)を同一のページについて複数登録可能(例えばブログ個別ページのトラックバック一覧とコメント一覧など)。
  4. ベースとなるページに全文が載っていなかったりリンク一覧しかないような場合()でも、リンク先の内容を読み込むように設定可能(出力例)。

■使い方その1:すでに対応するFeedパターン(パレット)が運良く存在する場合

  1. とりあえず、トップページでFeedを取得したいページのURLを入れて[パレット検索]してみる。
    f:id:furyu-tei:20090405052126p:image

    運が良ければ、対応するパレット一覧が表示される。
    f:id:furyu-tei:20090405105120p:image
  2. 運良く一覧が表示された場合、『プレビュー』をクリックしてみる。
    f:id:furyu-tei:20090405053130p:image

  3. 無事、目的とする内容がプレビューされたら、パレット一覧へともどって購読用Feedの種類を選択し、適当なRSSリーダに登録する。
    f:id:furyu-tei:20090405052230p:image

■使い方その2:目的とするFeedパターン(パレット)が存在しない場合

  1. Feedを取得したいページのURLを入れてみたが一覧が表示されない、または目的とする内容が一覧に無かった場合は『新規にパレット作成』をクリック。
    f:id:furyu-tei:20090405053743p:image

  2. (まだログインしていない場合は)ログイン画面が表示されるので自分のGoogle アカウントでログイン。
    f:id:furyu-tei:20090405104948p:image

  3. Feedパターン(パレット)の作成画面が表示されるので、必要な項目を入力*2
    f:id:furyu-tei:20090405054332p:image

  4. [確認]ボタンを押して、確認画面を表示。
    f:id:furyu-tei:20090405054457p:image

  5. 無事、目的とする内容が取得出来ていたら、[登録]ボタンを押して、登録。正常に登録出来れば、自分で作成したパレット一覧の一番上に表示される。
    f:id:furyu-tei:20090405054612p:image
  6. あとは使い方その1と同様、Feedを取得したいページのURLを入れて検索する。

■その他の使い方

  1. 自分で作成したパレットは、『パレット編集』をクリックすることで、編集(修正)可能。
  2. パレット一覧にある『このパレットを雛形にして新規作成』をクリックすると、当該パレットの各種設定がコピーされた新規作成画面が表示されるので、必要な部分だけ修正して登録可能。

■注意事項など

  1. 例によって、保証はありません。自己責任にてお試し下さい。
  2. 編集できるのは自分で作ったパレットだけです。
  3. 一度作成されたパレットは自分で作ったパレットを含め、削除は出来ません。どうしても削除する必要がある場合は、この記事にコメントを付けるなどして筆者にお知らせ下さい。
  4. 重いパレット(リンクを辿って全文読み込みをしたり、複雑なXPathを指定したりしているパレット)の場合、時間がかかりすぎてGoogle App Engineの制限にひっかかり、Feed取得に失敗する場合があります。
  5. サービスは止むをえぬ事情により突然休止/停止することがあります。
  6. 登録されたパレットに関して、止むをえぬ事情により、予告無く削除/編集される場合があります。

*1RSSクリエイターとか。RSS配信されていないサイトをRSSで配信してくれるサービスまとめ - Blog.IKUBON.comで紹介されているサービスとか。

*2:各項目の詳細説明はいまは省略します、すみません……その内やる気がでたらまとめる……かも。

edvakfedvakf 2009/04/08 01:20 自分の使い方が悪いだけなのかもしれませんが、このパレットを作ったのですが、
http://feedpalette.appspot.com/?key=agtmZWVkcGFsZXR0ZXIUCxINZGJGZWVkUGFsZXR0ZRjnNww

本文のところに //div[@class="index"]/p と書くと、タイトルに //div[@class="index"]/h3 と書いてあるにもかかわらず h3 ではなくて p の内容が出るみたいです。本文とタイトルを入れ替えると、今度は本文もタイトルも h3 の内容になってしまいました。

また、リンクのところに //div[@class="index"]/h3/a/@href と書いたのですが、反映されません。ただし、本文のところにこの XPath を書くと、本文もタイトルもリンク URL になりました。

お手上げだったので質問してみました。

furyu-teifuryu-tei 2009/04/08 02:03 リンクやタイトルが『本文に対して前にある』ことを明示するため、「位置」のradioボタンのチェックを「前」に変更しておく必要があります。
(勝手に修正してしまいましたが、いかがでしょうか?)

サイトによってタイトルやリンクの位置が本文の前/本文中/本文の後ろのいずれにあるかはまちまちなので、こんな風に指定するようにしています(最初は相対パスで考えていたのですが、自分的にはかえってややこしくなってしまったので……)。
わかりにくい仕様で申し訳ありません……。

edvakfedvakf 2009/04/08 04:03 バッチリです! ありがとうございました。

Lhankor_MhyLhankor_Mhy 2009/04/10 15:47 こんにちは。
これ便利ですね、使わせていただきます。

ところで、フィードの表示件数やサイズに制限がありますか?

furyu-teifuryu-tei 2009/04/10 20:14 Lhankor_Mhyさん、どうもです。
フィードのサイズ制限は基本的にはない(というかGAEで取得出来るファイルサイズに依存)です。

件数は、デフォルトで
1. 全文読み込み(B-1)チェック時:5件
2. 全文読み込み(B-1)チェックなし:10件
にしてあります(元ページにそれだけの件数が無ければそれ以下になりますが)。

隠しオプション(?)としてFeed取得時のURLに"&num=(件数)"を追加すればそれ以上取得することも可能ではありますが(30件まで)、その場合はGAEの処理時間制限(約30秒でタイムアウト)の問題がありますのであまりおすすめしません。

Lhankor_MhyLhankor_Mhy 2009/04/10 20:35 なるほど。
 
そうすると、はてブお気に入りみたいな更新が激しいページをLDRで受けると、クロール間隔の関係で抜けが出やすくなりそうですね。ありがとうございました。

ytsuchiyamaytsuchiyama 2009/04/28 15:24 "Yahoo ニュース一覧 うまく動きません" というのを作ってみましたが、そのとおりうまく動きませんでした。お手数ですが一旦削除して下さい。

furyu-teifuryu-tei 2009/04/28 21:00 ytsuchiyamaさん、どうもです。
ご要望のパレットは削除させていただきました。

どうも、GAEから
http://dailynews.yahoo.co.jp/fc/domestic/swine_flu_in_japan/news_list/?pn=1
をurllib2で取得しようとすると、うまく取れずに
http://dailynews.yahoo.co.jp/fc/domestic/swine_flu_in_japan/
にリダイレクトされてしまっているようです。
時間が取れたら、もう少し調べてみようと思いますが、対策は難しいかもしれません。

ytsuchiyamaytsuchiyama 2009/05/24 13:58 不動産金融ニュースウォッチ というのを作ってみましたが、うまく動きませんでしたので、一旦削除して下さい。
当該サイトを見ていただくとわかりますが、サイト上部に見出し一覧があって更新されてゆき、リンクはそのサイト下部の記事本文に飛ぶというものです。本文はともかく見出しだけでもrssで拾えればと思ったのですが、3時間毎のクロールで、同じ内容が再配信されてしまいます。

furyu-teifuryu-tei 2009/05/24 18:43 id:ytsuchiyamaさん
ちょっと手直ししてみましたが、これでいかがでしょうか。
http://feedpalette.appspot.com/?key=agtmZWVkcGFsZXR0ZXIVCxINZGJGZWVkUGFsZXR0ZRjgrgEM&url=http%3A//www.real-solution.biz/f_news/

ytsuchiyamaytsuchiyama 2009/05/25 08:46 おお、有難うございます。無理かと思っていたのですが、なかなか柔軟に対応できるものなのですね。

TenTen 2010/05/26 02:57 hi furyu-tei

I have encounter a coding problem.

I hope that you can read English =]

How can you solve this coding problem on feedpalette?
どのようにfeedpaletteこのコーディングの問題を解決できますか?

Thanks
=========================

<type 'exceptions.UnicodeDecodeError'>: 'ascii' codec can't decode byte 0xa9 in position 3388: ordinal not in range(128)
Traceback (most recent call last):
File "/base/data/home/apps/XXX/1.342204173822013186/get.py", line 9, in <module>
data=str(r.content).encode('utf-8')

=========================

#coding=utf-8
# -*- coding: utf-8 -*-
#import sys
#reload(sys); sys.setdefaultencoding('utf-8')
from google.appengine.api import urlfetch

r = urlfetch.fetch('http://www.google.com.hk', method="GET", follow_redirects="True")

data=str(r.content)

from BSXPath import BSXPathEvaluator,XPathResult

document = BSXPathEvaluator(data.encode('utf-8'))

nodes = document.getItemList('id("addlang")/a[1]')

print(nodes)

furyu-teifuryu-tei 2010/05/26 09:22 Hi, ten.
It is not a probrem of feedpalette, but BSXPath, isn't it?
So, try pass the content to BSXPathEvaluator directly.
It's mean,
document = BSXPathEvaluator(data.encode('utf-8'))
to
document = BSXPathEvaluator(r.content)

BSXPath use BeautifulSoup, yow know, and it has auto encoder/decoder.

TenTen 2010/05/26 13:29 Thanks for your reply.

Yes , it is not the problem of feedpalette. The reason I point out is that my programme using BSXPath has a problem, but feedpalette does not have that problem, so I am asking for your help . Sorry for any misconstrue.

I am using BeautifulSoup version 3.1.0.1

I have passed the content directly, but the same coding problem arises again.
==================
UnicodeEncodeError: 'ascii' codec can't encode characters in position 36-39: ordinal not in range(128)

==================

#coding=utf-8
# -*- coding: utf-8 -*-
#import sys
#reload(sys); sys.setdefaultencoding('utf-8')
from google.appengine.api import urlfetch

r = urlfetch.fetch('http://www.google.com.hk', method="GET", follow_redirects="True")

#data=r.content

from BSXPath import BSXPathEvaluator,XPathResult

document = BSXPathEvaluator(r.content)

nodes = document.getItemList('id("gbar")')

print(nodes)

TenTen 2010/05/26 16:33 And would you mind testing my script with the information below ?

I can get the content at feedpalette , but I cannot get the content via my script. After the web content have undergone BeatifulSoup process , some important information is gone, but this is not the case of feedpalette, why ?

URL : http://www.centralfield.com:443/2004/price/cpu.asp

XPath : /html/table[2]/tbody/tr[2]/td/table/tbody/tr/td[@class="style1"][1]

(**/home/body is not used because there is no "body" at all)

TenTen 2010/05/26 16:33 And would you mind testing my script with the information below ?

I can get the content at feedpalette , but I cannot get the content via my script. After the web content have undergone BeatifulSoup process , some important information is gone, but this is not the case of feedpalette, why ?

URL : http://www.centralfield.com:443/2004/price/cpu.asp

XPath : /html/table[2]/tbody/tr[2]/td/table/tbody/tr/td[@class="style1"][1]

(**/home/body is not used because there is no "body" at all)

TenTen 2010/05/26 16:43 (**/html/body is not used because there is no "body" at all)

furyu-teifuryu-tei 2010/05/26 21:40 I am using BeautifulSoup version 3.0.7a on feedpalette.
Once I tested BSXPath on BeautifulSoup version 3.1.0*, but it frequently failed at parsing, since then I use version 3.0.7* and I'm sorry I have not tested any other versions.

TenTen 2010/05/27 00:46 I think this is BeautifulSoup's problem.
I have changed to version 3.0.7a , some webs are working well , but some do not.

Is there any way to print out all things in the HTML objects obtained in BSXPath ?

Or did you add something special when running feedpalette? (It would be appreciated if you can open source it, haha, you can send it to my email =] )

I have added <<document = BSXPathEvaluator(r.content.replace("\"", "=\"")) >>to debug some errors

For example (I can get nothing from the content):
http://www.cheaphk.com/specials.php
//td[@class="smallText"][1]/table/tbody/tr[1]/td[2]/a

/html/body/table[3]/tbody/tr/td[2]/div/table/tbody/tr[2]/td/table/tbody/tr/td[@class="smallText"]/table/tbody/tr[1]/td[2]/a

--------------
http://www.agrade.com.hk/search.php?encode=YToyOntzOjU6ImludHJvIjtzOjM6ImhvdCI7czoxODoic2VhcmNoX2VuY29kZV90aW1lIjtpOjEyNzQ4ODc3ODY7fQ==

id("compareForm")/div[@class="cateGoodList"]/ul[@class="clearfix"]/li[@class="goodsText"]/a/b
-------------------
http://www.vivaphoto.com/shop/category.php?id=9

//div[@class="General_goodsBox"]/p/a

id("areaRight")/form[@name="compareForm"]/div[@class="goodsListBg clearfix"]/div[@class="General_goodsBox"]/p/a
--------------
But , google.com.hk and centralfield are working well

furyu-teifuryu-tei 2010/05/27 11:02 I have tested your URLs & XPaths on my local emvironment, and were almost fine.

(*) Only 'http://www.vivaphoto.com/shop/category.php?id=9' was returned '404'(Not found).
(*) use urllib2.urlopen() instead of urlfetch.fetch()
Environment:
Windows XP SP3(Japanese version)
Python 2.5.4
BeautifulSoup.py 3.0.7a (not modified)
BSXPath.py 0.01e

TenTen 2010/05/27 14:16 It's very interesting that if I use urllib2, almost all sites can be parsed. However, if I go to http://www.vivaphoto.com/shop/category.php?id=9 via urllib, it returned 404, while urlfetch return the normal site. And, feedpalette return the normal site and can parse the required information, how come ? I have tested the url in my computer(same OS , and the softwares version) and on GAE (real environment @ Google), both of them return 404. What does feedpalette use? urllib or urllib2 or urlfetch?

In addition, of course, if you go to the url via browser, it return the normal result 200.

Thanks.

furyu-teifuryu-tei 2010/05/27 16:38 Perhaps that mentioned site woult check 'User-Agent' header.
See
http://furyu-tei.sakura.ne.jp/archives/bsxp_test.zip
(my simple tests and results)

TenTen 2010/05/27 17:21 Yes , it's related to the header (user-agent) . I have just discovered that, thanks.

One more question, would you mind telling me what is xpathsupport's noscript using?

Because when I use it to go to google.com, it shows me a Japanese Google Page instead of a US Google Page (which is fetched by GAE supposedly)

One more point: if I use urlfetch or urllib2 to fetch the site, some images which do not have an absolute link(eg http://xxx.com/xxx.img) cannot show properly. However, while I view the source of noscript, only the non-absolute path which is same as normal browsing can be seen. Why ?

Thanks.

You can compare the pages below:

http://feedpalette.appspot.com/xpathsupport?url=http://www.google.com

http://ipgoto.appspot.com/www.google.com

furyu-teifuryu-tei 2010/05/27 21:10 Hi, Ten.

(1) My script would added some http-header-elements to call urllib2, so it shows you a Japanese one.
These are:
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Accept-Language: ja,en-us;q=0.7,en;q=0.3
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
Cache-Control: no-cache,max-age=0

(2) I would insert 'base' element in 'head' element, so you can see absolute link urls of image.


-----
(Sample)
req=urllib2.Request('http://www.google.com/')
req.add_header( ... , ... )
# Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
# Accept-Language: ja,en-us;q=0.7,en;q=0.3
# User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
# Cache-Control: no-cache,max-age=0
rsp=urllib2.urlopen(req)
content=rsp.read()
final_url=rsp.geturl()

document=BSXPathEvaluator(content)
head=document.getFirstItem('//head')
if head:
base=Tag(document,'base')
base['href']=final_url
head.insert(0,base)

TenTen 2010/05/27 23:51 hi Furyu-tei,

Thanks for telling me you have changed inserted a head element. After you telling me that, I figured it out, haha.

where is the Tag ? I may try to use content.replace('<head>','xxx')

and how to print the result ? print(document) cannot be used ...

Thanks.

TenTen 2010/05/28 00:07 hi

I have solved the problem with the code below , thanks.

Your work is well done !!!

from BSXPath import BSXPathEvaluator,XPathResult
document=BSXPathEvaluator(content)
head=document.getFirstItem('//head')

if head:
base='<base href="'+final_url+'">'
head.insert(0,base)

nodes = document.getFirstItem('/html')
print(nodes)

furyu-teifuryu-tei 2010/05/29 02:57 Hi, Ten. I'm glad that you solved the problem.
I'm sorry, I forget to write about 'Tag'.
That is a class of BeautifulSoup(from BeautifulSoup import Tag).

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証