質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

1回答

5268閲覧

frameタグが使われているサイトのスクレイピング方法を教えていただけませんか

dlrowolleh

総合スコア120

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2017/01/17 21:30

編集2017/01/18 22:03

似たような質問ばかりしてしまい、大変恐縮ですが何卒よろしくお願いします。
###前提・実現したいこと
APIが提供されていない、
ウェブサイトを監視するプログラムを作りたいです。
大気の状態を通知してくれるWebアプリを作りました | mawatari.jp
都道府県・時刻別そらまめ君URL - はてなダイアリー
のようなことがやりたいです。
対象サイトは
港区台場 - 大気汚染物質広域監視システム(そらまめ君)ホームページ
です。
LinuxのPCで
年月日、時間、OX、風向きのデータを保存、
OXが一定値を超えていたら、メールで通知みたいなことを考えています。(mailコマンド)
Rubyで実現したいのですが、どのようにすればいいでしょうか。

###問題点
APIが提供されていない、
frameタグで関連付けられているsrcのファイルを表示しているため、やり方が分からない。

様々な書籍を参考にさせていただきましたが
SBクリエイティブ:Rubyによるクローラー開発技法
Spidering Hacks――ウェブ情報ラクラク取得テクニック101選
よくわかりませんでした。
そのようなサイトへのスクレイピングはどのように行うのが一般的なのでしょうか。

###試したこと
RubyのMechanizeを使用しました。

Ruby

1 1 require "mechanize" 2 2 agent = Mechanize.new 3 3 agent.user_agent_alias = "Windows Chrome" 4 4 5 5 top = "http://soramame.taiki.go.jp/" 6 6 id = "DataList.php?MstCode=13108020" 7 7 url = top + id 8 8 9 9 page = agent.get(url) 10 10 page.root.xpath("//frame").each do |frame| 11 11 if frame["name"] == "Hyou" 12 12 frame_url = frame["src"] 13 13 frame_page = agent.get(frame_url) 14 14 open("/home/pc/Desktop/hoge/work/hoge.html","w"){|f| f.write frame_page.body.force_encoding(frame_page.encoding).encode("utf-8")} # utf-8に変換して書く場合 15 15 end 16 16 end 17 17 18 18 puts page.body.force_encoding(page.encoding).encode("utf-8")

でsrcファイルがhoge.htmlに保存できました。

HTML

1<html> 2<head> 3<META http-equiv="Content-Type" content="text/html; charset=EUC-JP"> 4<title>ページのタイトル</title> 5</head> 6<frameset rows="180,*" cols="*" frameBorder="0"> 7 <frame name="Titke" src="DataListTitle.php?MstCode=01234567&Time=2017011804" scrolling="no"> 8 <frame name="Hyou" src="DataListHyou.php?MstCode=01234567&Time=2017011804" scrolling="yes"> 9</frameset> 10<noframes></noframes> 11</html>

また、GoogleCromeでXpathを取得しました。

frameに関連づけられているファイル(DataListHyou.php?MstCode=01234567&Time=2017011804)

1 <html> 2 <head> 3 <title>ページのタイトル</title> 4 <link rel="stylesheet" media="all" href="Styles.css" type="text/css"> 5 <META http-equiv="Content-Type" content="text/html; charset=EUC-JP"> 6 <script language="javascript"> 7 <!-- 8 function Check(){ 9 ▸-if(document.Form1.Err.value!=""){ 10 ▸-▸-parent.location="ErrMsg.php?Err="+document.Form1.Err.value; 11 ▸-} 12 ▸-▸- 13 } 14 --> 15 </script> 16 17 </head> 18 19 <body MS_POSITIONING="GridLayout" class="bodyInfo" onLoad="Check()"> 20 <form name="Form1" action=""> 21 <input type="hidden" name="Err" value=""> 22 ▸-<table border="0" cellpadding="0" cellspacing="0" style="position:absolute; top:0px; left:5px;"> 23 ▸- <tr> 24 ▸-<td> 25 ▸-▸-<table style="font-size:12px;" border="1" class="hyoMenu" width="870"> 26 ▸-▸-▸-▸-▸-<tr align="right"> 27 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 28 ▸-▸-▸-▸-<td width="20" bgcolor="#FFFFCC">データ</td> 29 ▸-▸-▸-▸-<td width="20" bgcolor="#FFFFCC">データ</td> 30 ▸-▸-▸-▸-<td width="20" bgcolor="#FFFFCC">データ</td> 31 ▸-▸-▸-▸- 32 ▸-▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 33 ▸-▸-▸-▸-▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 34 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 35 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 36 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 37 ▸-▸-▸-▸-▸-▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 38 ▸-▸-▸-▸-▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 39 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 40 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 41 ▸-▸-▸-▸-▸-▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 42 ▸-▸-▸-▸-▸-▸-▸-▸-<td width="45" bgcolor="#FFFFCC">データ</td> 43 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 44 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td> 45 ▸-▸-▸-▸-<td width="40" bgcolor="#FFFFCC">データ</td>

45行目が

/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[18]

に該当するので、
取得したいXpathは
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[18] 年
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[18] 月
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[18] 日
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[18] 時間
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[18] OXの値
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[18] 風向き
です。

C

1#include<stdio.h> 2 3int main(void){ 4 int i = 0; 5 int j = 0; 6 for(i=1;i<=192;i++){ 7 for(j=1;j<=17;j++){ 8 if(j>4&&j<17&&j!=10){ // 4〜17の間は 9 continue; // 処理しない 10 } // ためのループ 11 printf("/html/body/form/table/tbody/tr/td/table/tbody/tr[%d]/td[%d]\n",i,j); 12 } 13 } 14 return 0; 15}

/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[1]
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[2]
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[3]
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[4]
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[10]
/html/body/form/table/tbody/tr/td/table/tbody/tr[1]/td[17]
/html/body/form/table/tbody/tr/td/table/tbody/tr[2]/td[1]
〜省略〜
/html/body/form/table/tbody/tr/td/table/tbody/tr[191]/td[2]
/html/body/form/table/tbody/tr/td/table/tbody/tr[191]/td[3]
/html/body/form/table/tbody/tr/td/table/tbody/tr[191]/td[4]
/html/body/form/table/tbody/tr/td/table/tbody/tr[191]/td[10]
/html/body/form/table/tbody/tr/td/table/tbody/tr[191]/td[17]
/html/body/form/table/tbody/tr/td/table/tbody/tr[192]/td[1]
/html/body/form/table/tbody/tr/td/table/tbody/tr[192]/td[2]
/html/body/form/table/tbody/tr/td/table/tbody/tr[192]/td[3]
/html/body/form/table/tbody/tr/td/table/tbody/tr[192]/td[4]
/html/body/form/table/tbody/tr/td/table/tbody/tr[192]/td[10]
/html/body/form/table/tbody/tr/td/table/tbody/tr[192]/td[17]

とできたのでうまく利用できないかと思っています。
質問を大幅に変更しました。失礼しました。
###補足情報(言語/FW/ツール等のバージョンなど)
環境はUbuntu です。
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-linux]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

frame内の要素は、frameに関連づけられているファイルを別途取得してスクレイピングする必要があると思います。

また、Google ChromeでXPathを取得した場合の注意事項として、存在しないtbodyが混入する問題があります。実際のHTMLにはtbodyはないので、tbodyを消したXPathの方が正しいかもしれません。

/html/body/form/table/tr/td/table/tr[1]/td[18]

parser errorの件は、取得したHTMLが文法的に問題があるのかもしれませんが、無視しても問題ない場合も多いです。

※ただし、この辺はスクレイピングツールの仕様によるかもしれないですが...

明確な回答ではありませんが、参考になれば幸いです。

投稿2017/01/17 22:00

編集2017/01/17 22:13
popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問