人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

JavaScriptで、http://hoge.jp/index.htmlを指定し、リンクURL(hrefとPOST、GET先)をたどる方法を教えてください。
結果は、配列でもオブジェクトでもテキスト形式の一覧でも、中身を見て操作できるものなら、何でも良いですが、理想をいうと、別ドメインのリンクは打ち切る等々の処理をしたいので、1階層ごとにたどる方法が良いです。
→ あとはそれを再帰的に呼び出す

●質問者: P-mako
●カテゴリ:インターネット ウェブ制作
✍キーワード:href JavaScript URL オブジェクト テキスト
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● ardarim
●23ポイント

こんな感じでどうでしょう?あんまりきれいじゃないかもですが...

function getxmlhttp()
{
 if(window.XMLHttpRequest){
 return window.XMLHttpRequest();
 }
 if(window.ActiveXObject){
 try {
 return new ActiveXObject("MSXML2.XMLHTTP");
 } catch(e){
 return new ActiveXObject("Microsoft.XMLHTTP");
 }
 }
 return null;
}

function geturl(url)
{
 var xmlhttp;
 var html = "";

 try {
 xmlhttp = getxmlhttp();
 xmlhttp.open("GET", url, false);
 xmlhttp.send();
 html = xmlhttp.responseText;
 xmlhttp = null;
 } catch(e){
 return "";
 }
 return html;
}

function getdoc(url)
{
 var oDoc = document.createDocumentFragment();
 var oDiv = document.createElement("DIV");
 oDiv.insertAdjacentHTML("beforeEnd", "<base href='" + url + "'>" + geturl(url));
 oDoc.appendChild(oDiv);

 return oDoc;
}

function getlink(oDoc, tag, attr)
{
 var ar = new Array;

 var oElements = oDoc.getElementsByTagName(tag);
 for(var i = 0; i < oElements.length; i++){
 ar.push(oElements[i][attr]);
 }

 return ar;
}

var oDoc = getdoc(http://hoge.jp/index.html);

var arAnchors = getlink(oDoc, "A", "href"); // A hrefの配列
var arImages = getlink(oDoc, "IMG", "src"); // IMG srcの配列
var arForms = getlink(oDoc, "FORM", "action"); // FORM actionの配列

getlinkの引数を変えれば他のタグも取れます。

エラー処理など詳細は入れていません。


URLはダミー

http://q.hatena.ne.jp/1169100350

◎質問者からの返答

ご回答ありがとうございます。

getdoc()、getlink()内で、それぞれ以下のエラーが出ます。

エラー: oDiv.insertAdjacentHTML is not a function

ソースファイル:

oDiv.insertAdjacentHTML("beforeEnd", "<base href='" + url + "'>" + geturl(url));


エラー: oDoc.getElementsByTagName is not a function

ソースファイル:

var oElements = oDoc.getElementsByTagName(tag);


2 ● ardarim
●23ポイント

ブラウザは何をお使いでしょうか?


IE6では動作しています。

insertAdjacentHTMLはIE独自なのでIE以外ではこのままでは動作できません。


概要としては

(1)XMLHTTPを使って指定URLからHTMLを取得(geturl)

(2)HTMLからDOMを生成(getdoc)

(3)DOMからリンクを抽出(getlink)

といった感じです。


IEの場合はinsertAdjacentHTMLでHTMLからDOMに変換してくれますので、自力でHTMLを解析する必要がありません。

IE以外の場合は同等のブラウザ独自メソッドがあればそれを利用するか、自力でHTMLを解析しなくてはなりません。


エラー: oDoc.getElementsByTagName is not a function

については、DocumentFragmentの実装がIEと異なっているのかもしれません。その場合はノードを1つずつたどって行ってAタグ(や他のタグ)を自力で探す方法が必要かもしれません。


ダミー

http://q.hatena.ne.jp/1169100350

◎質問者からの返答

IE6(6.0.2900.2180.*)でエラーになります。

※1度目の回答のエラーメッセージは、エラー詳細確認のためFireFoxで表示されたものです。

ちなみにgetdoc()に渡すパラメータも文字列扱いが正しいと思われるので、ダブルクォート or シングルクォートで囲う必要がありそうです。

実際に上手くいったソースをそのまま貼り付けていただけると助かります。


3 ● ardarim
●21ポイント

こちらではローカルで動かしていたためうまく動いていたようです。Webサーバにアップした状態で行うと、動作しませんでした。確認不足ですみません。IEのバージョンは同じでした。


xmlhttp.open()が失敗してgeturl()の結果が""になることが原因のようです。

xmlhttp.open()は、セキュリティ上の制限で他ドメインのURLからの取得はできないようです。


IEのセキュリティゾーン設定を変更するとこの制限を制御できます。

[ツール]-[インターネットオプション]-[セキュリティ]を開き、各ゾーンの[レベルのカスタマイズ]の中で[その他]-[ドメイン間でのデータソースのアクセス]の状態によってこの制限の有効/無効を制御します。


通常、インターネットゾーンではこの設定は「無効」になっていますので、他ドメインのURLを対象にしたxmlhttp.open()がエラーになります。信頼済みサイトは「有効」になっていますので、自分のスクリプトを置いたドメインを信頼済みサイトに追加することで動作するようになります。

◎質問者からの返答

度々のご回答ありがとうございます。

ドメイン間でのデータソースアクセスを有効にしても、同一サーバ上、およびローカルともに状況は変わりません。

また信頼済みサイトに登録して、サーバ上にアップしても同じです。

→ oDiv.insertAdjacentHTML でinsertAdjacentHTMLが未定義エラーです。


4 ● ardarim
●23ポイント ベストアンサー

以前書いたものとほとんど違いはありませんが、いちおう動作しているHTML全体を載せておきます。(少しエラー処理は追加しました)

<HTML>
<HEAD>
<title>test</title>
</HEAD>
<BODY>

<script language="JavaScript">

function getxmlhttp()
{
 if(window.XMLHttpRequest){
 return window.XMLHttpRequest();
 }
 if(window.ActiveXObject){
 try {
 return new ActiveXObject("MSXML2.XMLHTTP");
 } catch(e){
 return new ActiveXObject("Microsoft.XMLHTTP");
 }
 }
 return null;
}

function geturl(url)
{
 var xmlhttp;
 var html = "";

 try {
 xmlhttp = getxmlhttp();
 xmlhttp.open("GET", url, false);
 xmlhttp.send();
 html = xmlhttp.responseText;
 xmlhttp = null;
 } catch(e){
 alert(e.description);
 return "";
 }
 return html;
}

function getdoc(url)
{
 var oDoc = document.createDocumentFragment();
 var oDiv = document.createElement("DIV");
 var html = geturl(url);
 if(html == ""){
 alert("URLを取得できません");
 return null;
 }
 oDiv.insertAdjacentHTML("beforeEnd", "<base href='" + url + "'>" + html);
 oDoc.appendChild(oDiv);

 return oDoc;
}

function getlink(oDoc, tag, attr)
{
 var ar = new Array;

 var oElements = oDoc.getElementsByTagName(tag);
 for(var i = 0; i < oElements.length; i++){
 ar.push(oElements[i][attr]);
 }

 return ar;
}


function test()
{

 result.innerHTML = "";

 var oDoc = getdoc(urlstr.value);

 var ar = getlink(oDoc, "A", "href");
 for(i = 0; i < ar.length; i++){
 document.all("result").insertAdjacentHTML("beforeEnd", "A[" + i + "] " + ar[i] + "<br>");
 }

 ar = getlink(oDoc, "IMG", "src");
 for(i = 0; i < ar.length; i++){
 document.all("result").insertAdjacentHTML("beforeEnd", "IMG[" + i + "] " + ar[i] + "<br>");
 }

 ar = getlink(oDoc, "FORM", "action");
 for(i = 0; i < ar.length; i++){
 document.all("result").insertAdjacentHTML("beforeEnd", "FORM[" + i + "] " + ar[i] + "<br>");
 }

}

</script>

<input type=text name="urlstr" size=80 value="http://www.example.com/">
<input type=button onclick="javascript:test();" value="解析">
<form action="test.htm" method="GET">
</form>

</BODY> </HTML>

環境は同じだと思いますので、なぜ動かないのかはこれ以上は推測が難しいです。どこでエラーになっているのかデバッグする必要があるでしょう。


ダミー

http://q.hatena.ne.jp/1169100350

◎質問者からの返答

が必要でしたが、Yahooで問題なく動作しました。

ローカル上に保存したHTMLでも、セキュリティ保護のポップアップ(とうかIEツールバー下の警告バー?)が出ただけで、「実行許可」にすれば問題なく動作しました。

ありがとうございます。

これはいろいろな局面で使えそうなサンプルになりました。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ