JavaScriptで、http://hoge.jp/index.htmlを指定し、リンクURL(hrefとPOST、GET先)をたどる方法を教えてください。

結果は、配列でもオブジェクトでもテキスト形式の一覧でも、中身を見て操作できるものなら、何でも良いですが、理想をいうと、別ドメインのリンクは打ち切る等々の処理をしたいので、1階層ごとにたどる方法が良いです。
→ あとはそれを再帰的に呼び出す

回答の条件
  • URL必須
  • 1人5回まで
  • 登録:2007/01/18 15:05:52
  • 終了:2007/01/24 16:45:33

ベストアンサー

id:ardarim No.4

ardarim回答回数896ベストアンサー獲得回数1442007/01/23 02:36:58

ポイント23pt

以前書いたものとほとんど違いはありませんが、いちおう動作している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

id:P-mako

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

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

ありがとうございます。

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

2007/01/24 16:44:54

その他の回答(3件)

id:ardarim No.1

ardarim回答回数896ベストアンサー獲得回数1442007/01/19 04:05:32

ポイント23pt

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

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

id:P-mako

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

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);

2007/01/19 16:03:59
id:ardarim No.2

ardarim回答回数896ベストアンサー獲得回数1442007/01/20 01:28:01

ポイント23pt

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


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

id:P-mako

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

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

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

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

2007/01/20 14:10:29
id:ardarim No.3

ardarim回答回数896ベストアンサー獲得回数1442007/01/20 20:57:20

ポイント21pt

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


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

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


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

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


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

id:P-mako

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

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

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

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

2007/01/22 11:32:30
id:ardarim No.4

ardarim回答回数896ベストアンサー獲得回数1442007/01/23 02:36:58ここでベストアンサー

ポイント23pt

以前書いたものとほとんど違いはありませんが、いちおう動作している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

id:P-mako

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

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

ありがとうございます。

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

2007/01/24 16:44:54
  • id:ardarim
    アップロードする際に、divタグが抜けてしまったようです。(>| ~ |< 記法にしても div だけは有効になってしまうようですね...)

    &lt;/form&gt;の後に&lt;div id="result"&gt;&lt;/div&gt;を追加してください。
  • id:ardarim

    </form>の後に<div id="result"></div>を追加してください。
    です

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません