【最大10000ポイント】当たる!!質問投稿キャンペーン!

質問を閉め切った直後に気付いたもので、すいません!!

QNo.3797932の、つづきなのですが、、、
教えていただいた以下の方法

-------------------------

#!/usr/local/bin/perl
use LWP::Simple;
use XML::RSS;
use LWP::UserAgent;

my $url = 'http://news.google.com/news?hl=ja&ned=us&ie=UTF- …
my $ua = new LWP::UserAgent;
my $responce = $ua->get($url, 'User-Agent' => 'Mozilla/4.0');
my $data_from_web = $responce->content;

print <<"HTML";
Content-type: text/html

<html>
HTML

print $data_from_web;

exit;

-------------------------

の場合だと、ページ表示データは取得できるのですが、RSS特有のタグが
抜け落ちる為、その後の解析ができない事に気付きました。

なんとか、RSS特有のタグも含めてのRSS情報を入手する方法はないでしょうか?

ちなみに、RSS特有のタグも含めてのRSS情報は、ブラウザーのURLの窓に
http://news.google.com/news?hl=ja&ned=us&ie=UTF- …
このアドレスを直接入力してリターンキーを押すと、確認する事ができます。

度々申し訳ないのですが、よろしくご指導、お願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

>で、目的はニュース記事のタイトルとリンク抽出なので、


>&gt;&lt;title&gt;
>と
>&lt;/title&gt;&lt;
>で囲まれた部分、及び、
>link&gt;&lt;guid isPermaLink=&quot;false&quot;&gt;
>と
>&lt;/guid&gt;&lt;
>に囲まれた部分を抽出する方法

やっぱり,回答1は的外れじゃないか(笑)
予想はしてたけど。

#!/usr/local/bin/perl
use LWP::Simple;
use XML::RSS;
use LWP::UserAgent;
use XML::XPath;
use XML::DOM;

sub getData{

my $url = 'http://news.google.com/news?hl=ja&ned=us&ie=UTF- …
my $ua = new LWP::UserAgent;
my $response = $ua->get($url, 'User-Agent' => 'Mozilla/4.0');
return $response->content;
}

sub getPairs{
my $data = @_[0];
my @pairs;
my $xp = new XML::XPath( xml => $data );
$hoge = $xp->findnodes("/rss/channel/item/title/text()");
$fuga = $xp->findnodes("/rss/channel/item/link/text()");
while($hoge->size() > 0 ){
push(@pairs,[$hoge->pop()->getNodeValue(),$fuga->pop()->getNodeValue()]);
}
return @pairs;
}

sub generateContent{

my $pairs = @_[0];
my @pair;
my $document = new XML::DOM::Document;

# not in DOM spec

my $xmlDecl = $document->createXMLDecl("1.0","UTF-8","no");
$document->setXMLDecl($xmlDecl);

# not in DOM spec
my $doctype = $document->createDocumentType("html","http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" ,"-//W3C//DTD XHTML 1.0 Strict//EN", "");
$document->setDoctype($doctype);
my $Eul = $document->createElement("ul");
while($#$pairs > 0){
$pair = pop(@$pairs);
my $Eli = $document->createElement("li");
my $Ea = $document->createElement("a");
$Ea -> setAttribute("href",$$pair[1]);
my $Ea_text = $document->createTextNode($$pair[0]);

$Ea->appendChild($Ea_text);
$Eli->appendChild($Ea);

$Eul->appendChild($Eli);
}

my $Ebody = $document->createElement("body");
$Ebody->appendChild($Eul);

my $Etitle = $document->createElement("title");
$title_text = $document->createTextNode("Q3798395 TestCase 1");
$Etitle->appendChild($title_text);

my $Ehead = $document->createElement("head");
$Ehead->appendChild($Etitle);

my $Ehtml = $document->createElement("html");
$Ehtml->setAttribute("xmlns","http://www.w3.org/1999/xhtml");
$Ehtml->appendChild($Ehead);
$Ehtml->appendChild($Ebody);


$document->appendChild($Ehtml);
return $document;

}

sub generateHTTPHeader{

my $headers = '';
$headers = $headers . 'Status: 200 OK' . "\n";
$headers = $headers . 'Content-Type:text/html;charset=UTF-8' . "\n\n";
return $headers;

}

sub Main{
# toString is not in DOM Spec. the output functionality is defined in DOM Level 3 Load and Save Module

#指定された文字列をp要素の子のテキストノードとして持つ,HTMLを生成。
#/まあ、生ソース自体は別にこんな事しなくてもContent-Typeをtext/plainとすれば出来るが。
print generateHTTPHeader();
my @arr = getPairs(getData());
print generateContent(\@arr)->toString;
exit;
}
Main();

exit;

#格好つけてXPathを使ってみたけど,XSLTのほうが楽そうだった気がする
#正規表現や文字符号化方式については俺詳しくないのでパス。なので意地でもDOMを使う(笑)

#ただし,このコードが取ってきているのは
#/rss/channel/item/title/text()
#だけで,
#/rss/channel/title/text()
#/rss/channel/link/text()
#や
#/rss/channel/image/title/text()
#/rss/channel/image/link/text()

については考えてない。
    • good
    • 0
この回答へのお礼

himajin100000様へ

実は、実は、、、、、、、
下の方~に既にレスを付けていたのですが以下の方法で全て解決することができました。

---

himajin100000様へ

ご指摘いただいた

「$all中にtitle要素はXHTML名前空間の1個しかなくlink要素は書いてないから存在しないからね?RSS 0.92名前空間(Or 名前空間なし)のlink要素およびtitle要素は存在しない」

この部分の意味がわかり、そして、

「ということは、逆に言えば、tamahiro22様から教えていただいたプログラムのHTMLの「ソース」の方には、実はtitleタグが入っているのではないか?(ブラウザーでの表示では見えなかった。ブラウザーで見えるもの=$allと勘違いしていました!)」

と気付き、実際に見てみると入っており、そして、以下のプログラムを作ったところ、イメージしていたものができました!

---

#!/usr/local/bin/perl
use LWP::Simple;
use XML::RSS;
use LWP::UserAgent;

my $url = '​http://news.google.com/news?hl=ja&ned=us&ie=UTF- …
my $ua = new LWP::UserAgent;
my $responce = $ua->get($url, 'User-Agent' => 'Mozilla/4.0');
my $data_from_web = $responce->content;

print <<"HTML";
Content-type: text/html

<html>
HTML

$_ = $data_from_web;

my @titles = $data_from_web =~ /<title>([^<]*)<\/title>/ig;
my @links = $data_from_web =~ /<guid isPermaLink=\"false\">([^<]*)<\/guid>/ig;

$no = 0;
foreach $value (@links){$news[$no]="<A HREF=\"$links[$no]\"TARGET=\"_new\">$titles[$no+2]</a><BR>";$no++}
$delete = pop @news;
foreach $value (@news){print $value;}

exit;

----

tamahiro22様からは、google newsからの特殊な情報入手の方法を教えていただき、himajin100000様からは、ブラウザーで見えているものと、perlが吐き出しているものとは違う!という事を気付かせていただき(こんな単純な事に長い間気付きませんでした!)、この2つ合わせ技のおかがで解決する事ができました!

今回、OKWaveを活用することにより、イメ-ジするものができたと同時に、いろいろと学ばせていただきました。
tamahiro22様、himajin100000様、OKWave、教えてgoo、皆様に心より感謝致します。

お礼日時:2008/02/23 10:39

何をやろうとしているのかが見えなかったから



なんか・・・・
>まさに、この様な形をイメージしていました。
と言われて安心した一方で,

やりたそうなこと見ているとこの回答でよかったんだろうか、って不安になってくる。
本当に?って聞き返したくなる。
この方法だとRSSはParseできないからね?

#この方針で書いているのは元のPerlソースに
html要素開始タグがあるから。終了タグがないのがよくわからんけど。

>$#T;
@Tはどこから来たんだ、@Tは。

言っておくけど,

$all中に
title要素はXHTML名前空間の1個しかなく
link要素は書いてないから存在しないからね?
RSS 0.92名前空間(Or 名前空間なし)のlink要素およびtitle要素は存在しない。

ブラウザで右クリックしてもらってソース見てもらえば解ると思うけど
RSSの文字列がTextNodeのnodeValueになるように
全部実体参照に展開されている。

(その見ている「ソース」が$allに入っている。)

あとXHTML名前空間のlink要素は旧SGMLの流れを汲んだHTML 4.01との互換性から
<link rel="stylesheet" href="hogehoge.css" />
みたいに省略されていることが殆どだから</link>が出てくることは少ないよ。
=======================
念のため,ここだけ不安なので理解しているか確認させて。当たり前ジャン、っていうかもしれないけど。ここが間違っていると絶対うまくいかないから。
========================
間違いない、って自信もてるんだったら考えてみるよ。
★テキストノードおよび属性値中に>は文字参照でもCDATAでもない形で存在できる
とか
★属性を持つlink要素が出現するかもしれない
とか

この回答への補足

>$all中にtitle要素はXHTML名前空間の1個しかなく
>link要素は書いてないから存在しないからね?
>ブラウザで右クリックしてもらってソース見てもらえば解ると思うけど
>RSSの文字列がTextNodeのnodeValueになるように
>全部実体参照に展開されている。

この言葉の意味に、送信した後に気付きました。

で、目的はニュース記事のタイトルとリンク抽出なので、

&gt;&lt;title&gt;

&lt;/title&gt;&lt;
で囲まれた部分、及び、

link&gt;&lt;guid isPermaLink=&quot;false&quot;&gt;

&lt;/guid&gt;&lt;

に囲まれた部分を抽出する方法をご指導いただければ幸です。

補足日時:2008/02/22 21:41
    • good
    • 0
この回答へのお礼

himajin100000様
ご指導、ありがとうございます。

>何をやろうとしているのかが見えなかったから

最終的な望む形は、perlからgoogleニュースに人名で検索をかけ、
その結果のデータをperlで入手し、リンク付タイトルで数行表示する事です。

>@Tはどこから来たんだ、@Tは。

それは、教えてgooのこのページから持ってきました。

http://oshiete1.goo.ne.jp/qa3143595.html

これを組み合わせれば、望む形が実現できるのではないかと思って。


>$all中にtitle要素はXHTML名前空間の1個しかなく
>link要素は書いてないから存在しないからね?

実際にプログラムを稼働させ、$allを表示させたところ、
<TITLE>タグで囲まれたニュースの見出しが10個確認できています。
(キーワードaikoで検索した結果です)

例えば、こんな感じで、、、


--------------------

< item>
<title>
aiko、デビュー10周年を記念して過去のアルバム7タイトルの初回限定盤を復刻。オールナイトニッポンにも久々の出演決定 - bounce
</title>

(中略)

<title>
aiko、過去の初回限定仕様盤が復刻! - エキサイト
</title>


以下同様に8つ。


--------------------

ということで、、、、

>$all中にtitle要素はXHTML名前空間の1個しかなく
>link要素は書いてないから存在しないからね?

これは、実際にプログラムを動かしてみてのことでしょうか?

私の方では、以下のプログラムでTITLEタグ10個確認しています。
(漢字でも検索できる様に変更しています)

------------------------------

#!/usr/local/bin/perl

use LWP::Simple;
use XML::RSS;
use LWP::UserAgent;
use XML::DOM;
sub getData{

my $keyword = 'aiko';

#URLエンコードを行う
$keyword=~s/([^0-9A-Za-z_])/'%'.unpack('H2',$1)/ge;
$keyword=~s/\s/+/g;

my $url = 'http://news.google.com/news?hl=ja&ned=us&ie=UTF- …
my $ua = new LWP::UserAgent;
my $response = $ua->get($url, 'User-Agent' => 'Mozilla/4.0');
return $response;
}

(中略)

sub Main{

$part1=generateHTTPHeader();
$part2=generateContent(getData()->content)->toString;
$all=$part1.$part2;

print $all;

exit;
}

Main();

お礼日時:2008/02/22 21:32

#!/usr/local/bin/perl


#ひょっとしてこんなの期待したの?解析云々は関係なしに
#ソースコードはBOMなしUTF-8の改行コードLF
use LWP::Simple;
use XML::RSS;
use LWP::UserAgent;
#要インストール
#http://www.edita.jp/musekininit/one/musekininit5 …
use XML::DOM;
sub getData{

my $url = 'http://news.google.com/news?hl=ja&ned=us&ie=UTF- …
my $ua = new LWP::UserAgent;
my $response = $ua->get($url, 'User-Agent' => 'Mozilla/4.0');
return $response;
}

sub generateContent{
my $text = @_[0];
my $document = new XML::DOM::Document;

# not in DOM spec

my $xmlDecl = $document->createXMLDecl("1.0","UTF-8","no");
$document->setXMLDecl($xmlDecl);

# not in DOM spec
my $doctype = $document->createDocumentType ("html", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" ,"-//W3C//DTD XHTML 1.0 Strict//EN", "");
$document->setDoctype($doctype);
#悩んだけど、熟知してないと非常に厄介なので、CDATAセクションにはしない
my $p_text = $document->createTextNode($text);
my $Ep = $document->createElement("p");
$Ep->appendChild($p_text);

my $Ebody = $document->createElement("body");
$Ebody->appendChild($Ep);

my $Etitle = $document->createElement("title");
$title_text = $document->createTextNode("Q3798395 TestCase 1");
$Etitle->appendChild($title_text);

my $Ehead = $document->createElement("head");
$Ehead->appendChild($Etitle);

my $Ehtml = $document->createElement("html");
$Ehtml->setAttribute("xmlns","http://www.w3.org/1999/xhtml");

$Ehtml->appendChild($Ehead);
$Ehtml->appendChild($Ebody);


$document->appendChild($Ehtml);
return $document;

}

sub generateHTTPHeader{

my $headers = '';
$headers = $headers . 'Status: 200 OK' . "\n";
$headers = $headers . 'Content-Type:text/html;charset=\'UTF-8\'' . "\n\n";
return $headers;

}

sub Main{
# toString is not in DOM Spec. the output functionality is defined in DOM Level 3 Load and Save Module

#指定された文字列をp要素の子のテキストノードとして持つ,HTMLを生成。
#/まあ、生ソース自体は別にこんな事しなくてもContent-Typeをtext/plainとすれば出来るが。
print generateHTTPHeader();
print generateContent(getData()->content)->toString;
exit;
}

Main();

この回答への補足

himajin100000様へ

ご指摘いただいた

「$all中にtitle要素はXHTML名前空間の1個しかなくlink要素は書いてないから存在しないからね?RSS 0.92名前空間(Or 名前空間なし)のlink要素およびtitle要素は存在しない」

この部分の意味がわかり、そして、

「ということは、tamahiro22様から教えていただいたプログラムのHTMLの「ソース」の方にはtitleタグが入っているのではないか?(ブラウザーでの表示では見えなかった。ブラウザーで見えるもの=$allと勘違いしていました!)」

と気付き、実際に見てみると入っており、そして、以下のプログラムを作ったところ、イメージしていたものができました!

-------------------------

#!/usr/local/bin/perl
use LWP::Simple;
use XML::RSS;
use LWP::UserAgent;

my $url = 'http://news.google.com/news?hl=ja&ned=us&ie=UTF- …
my $ua = new LWP::UserAgent;
my $responce = $ua->get($url, 'User-Agent' => 'Mozilla/4.0');
my $data_from_web = $responce->content;

print <<"HTML";
Content-type: text/html

<html>
HTML

$_ = $data_from_web;

my @titles = $data_from_web =~ /<title>([^<]*)<\/title>/ig;
my @links = $data_from_web =~ /<guid isPermaLink=\"false\">([^<]*)<\/guid>/ig;

$no = 0;
foreach $value (@links){$news[$no]="<A HREF=\"$links[$no]\"TARGET=\"_new\">$titles[$no+2]</A><BR>";$no++}
$delete = pop @news;
foreach $value (@news){print $value;}

exit;

-------------------------

tamahiro22様とhimajin100000様のアドバイスのおかげです!
ありがとうございました!!

イメ-ジするものができたと同時に、いろいろと学ばせていただきました。
心より感謝致します。

補足日時:2008/02/23 09:22
    • good
    • 0
この回答へのお礼

himajin100000様

ご指導いただき、ありがとうございます!!

>#ひょっとしてこんなの期待したの?

まさに、この様な形をイメージしていました。
詳しい説明付のリンクも含め、ありがとうございます。

BOMとは何なのかを調べ、その処理を行える
テキストエディターを入手し、着手してから3時間、
エラーの嵐(マックユーザーなので、コードの問題で
かなり時間をとられました)の末、正常に稼働できました。
ありがとうございます!

やっとのことで、データ入手でき、最後の仕上げとばかりに、
リンク付の見出しリスト出力の為、sub Mainの中を以下の様にしました。

sub Main{

$part1=generateHTTPHeader();
$part2=generateContent(getData()->content)->toString;
$all=$part1.$part2;

$_ = $all;

for(my $i=0; $i<=$#T; $i++){
$T[$i]=~s/<title>(.+)<\/title>/$1/;
$L[$i]=~s/<link>(.+)<\/link>/$1/;
print '<a href="'.$L[$i]."'>".$T[$i]."</a><BR>\n";
}
exit;
}
Main();

が、最後のこの部分がうまく稼働せず、半日、Internal Server Errorと格闘しています。
調べたところ「正規表現で処理する前にutf-8をEUCに変換しなければならない」との記述を見つけ、あれこれ試したのですが、うまくいきません。

文字コードの問題で、何もヒットせず、その場合はInternal Server Errorになってしまっている感じがしています。

尚、当初はXMLパースモジュールを使い処理するつもりでしたが、
それが、どうもうまくいかず、上記の様なシンプルな形で
処理しようとしています。


お手数をかけますが、最後のこの部分、ご指導いただければ幸です。

お礼日時:2008/02/22 19:29

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


人気Q&Aランキング