challenge HTTPでGET

HTTPで指定されたURLをGETするコードを書いてください。 URLは「http://ja.doukaku.org/feeds/comments/」とします。

もしOSに依存する場合はそのOS名のタグを、 依存しない場合は「OS非依存」というタグをつけてください。 わからなければつけなくても構いません。

このお題はところてんさんの投稿を参考にして作成しました。 ご投稿ありがとうございます。

なでしこ自体がWindows依存です...
1
"http://ja.doukaku.org/feeds/comments/"をHTTPデータ取得して表示
すみません、投稿する場所を間違ってしまいましたorz

Posted feedbacks - Nested

Flatten Hidden
1
ruby -rkconv -ropen-uri -e 'puts open(ARGV.shift).read.toeuc' http://ja.doukaku.org/feeds/comments/
文字コードの指定をUTF-8にしないとまずいのでは?
すみません、 上コメントは勘違いです。
ブラウザのアドレスバーに…
1
javascript:void (location.href='http://ja.doukaku.org/feeds/comments/')
1
2
3
4
#! /usr/bin/python
import urllib
u = urllib.urlopen('http://ja.doukaku.org/feeds/comments/')
print u.read()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
using System;
using System.Net;
using System.Text;
class Program
{
  static void Main()
  {
    string url = "http://ja.doukaku.org/feeds/comments/";
    WebClient wc = new WebClient();
    byte[] bb = wc.DownloadData(url);
    string s = Encoding.UTF8.GetString(bb);
    Console.WriteLine(s);
  }
}
参考にさせていただきました。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
open System;;
open System.Net;;
open System.Text;;

let getContents (url:string) =
    let webClnt = new WebClient() in
    let returnValue = webClnt.DownloadData( url ) in
    Encoding.UTF8.GetString( returnValue );;

let doukakuURL = "http://ja.doukaku.org/feeds/comments/";;

Console.WriteLine( getContents doukakuURL );;
Squeak Smalltalk で、エンコーディングと改行記号の変換も一緒に。
1
2
3
| stream |
stream := HTTPSocket httpGet: 'http://ja.doukaku.org/feeds/comments/'.
^stream contents withSqueakLineEndings convertFromEncoding: 'utf-8'
1
2
3
4
5
6
7
8
9
<script src="http://www.google.com/jsapi?key=YOUR_KEY_HERE"></script>
<script>
google.load('feeds', '1');
google.setOnLoadCallback(function () {
	new google.feeds.Feed('http://ja.doukaku.org/feeds/comments/').load(function (r) {
		if (!r.error) alert(r.feed.entries[0].title);
	});
});
</script>
基本的にどのブラウザ上でも動くはず。無駄にAjax。 なお、しばしばXMLHttpRequestとActiveXObjectの試す順番が逆に記述されているケースがありますが、IE7がXMLHttpRequestに対応したのでこの順の方が適当です。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var url = "http://ja.doukaku.org/feeds/comments/";

if (XMLHttpRequest) {
  var xhr = new XMLHttpRequest();
} else if (ActiveXObject) {
  try {
    var xhr = new ActiveXObject("Msxml2.XMLHTTP");
  } catch(e) {
    try {
      var xhr = new ActiveXObject("Microsoft.XMLHTTP");
    } catch(e) {
      var xhr = null;
    }
  }
} else {
    var xhr = null;
}

if (xhr != null) {
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) {
      document.write(xhr.responseText);
    }
  }
  xhr.open("GET", url, true);
  xhr.send(null);
}
1
perl -MLWP::Simple -e 'print LWP::Simple::get(shift)' http://ja.doukaku.org/feeds/comments/
VC++/MFCで。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <afxwin.h>
#include <afxinet.h>

const TCHAR* url = _T("http://ja.doukaku.org/feeds/comments/");

int _tmain()
{
	CInternetSession session(_T("MFC wget"));
	CHttpFile* pFile = (CHttpFile*)session.OpenURL(url);
	CString line;
	while (pFile->ReadString(line))
		fwprintf(stdout, _T("%S"), line);

	return 0;
}
fwprintfではなくて_ftprintf だった。キャストも古いほうだ。
iframe で
1
document.body.appendChild(document.createElement('iframe')).src='http://google.com';
うあ。URL も決まってたのね><すみません。
Windowsのみ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
require 'Win32/Console' # http://rubyforge.org/projects/win32console
require 'open-uri'
require 'uconv'

$cp = Win32::Console.OutputCP()
#ENV['HTTP_PROXY'] = "http://proxy.example.com:8080/"

uri = "http://ja.doukaku.org/feeds/comments/"

begin
  str = open(uri).read
rescue
  $stderr.puts $!
else
  if $cp == 932
    output = Uconv.u8tosjis(str)
  else
    output = str
  end
  print output
end
GETしてどうするか決まっていないのですが、標準出力にそのまま書き出しています。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import java.net.URL;
import java.net.URLConnection;
import java.io.InputStream;
import java.io.IOException;

public class Sample {

    static final String url = "http://ja.doukaku.org/feeds/comments/";
    static final int BUFFER_SIZE = 2048;

    public static void main(String[] args) throws IOException {
        URLConnection uc = new URL(url).openConnection();
        InputStream is = uc.getInputStream();
        byte[] buffer = new byte[BUFFER_SIZE];
        int r;
        while ((r = is.read(buffer)) > 0) {
            System.out.write(buffer, 0, r);
        }
    }
}
Tcl 標準の http パッケージで。
1
2
package require http
http::geturl http://ja.doukaku.org/feeds/comments/ -channel stdout
erl -noshell -s httpget httpget -s init stop
のように起動します.
1
2
3
4
5
6
-module(httpget).
-export([httpget/0]).

httpget() ->
    {ok, {Status, Header, Body}} = http:request("http://ja.doukaku.org/feeds/comments/"),
    io:format("Status: ~p~nHeader:~n~p~nBody:~n~s~n", [Status, Header, Body]).
とりあえずお手軽に。
1
2
3
4
<?php
$buffer = file_get_contents('http://ja.doukaku.org/feeds/comments/');
print $buffer;
?>
普通にやるとまんまJAVAなのでScalaらしく。接続は閉じてないけど気にしない。
1
2
3
4
5
6
7
8
9
import java.net._
import java.io._

val readLine = &(new BufferedReader(new InputStreamReader((new URL("http://ja.doukaku.org/feeds/comments/")).openStream))).readLine
def print_contents():Unit = readLine() match {
  case null => ()
  case s    => {println(s);print_contents}
}
print_contents
wininetを使ったネットアクセス windows限定
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#pragma comment(lib,"wininet.lib")
#include <stdio.h>
#include <windows.h>
#include <wininet.h>

int main()
{
	HINTERNET hInet;
	HINTERNET hFile;

	hInet = InternetOpenA("TEST",INTERNET_OPEN_TYPE_DIRECT,
		NULL,NULL,0);

	hFile = InternetOpenUrlA(hInet,
		"http://ja.doukaku.org/feeds/comments/",
		NULL,0,INTERNET_FLAG_RELOAD,0);
	
	unsigned char buf[1024];
	DWORD dwSize;

	do{
		InternetReadFile(hFile, buf, 1023, &dwSize);
		buf[dwSize] = '\0';
		printf("%s\n", buf);
	}while(dwSize);

	getchar();
}
普通にImport命令でインポートできます.
ただ,形式を指定してあげないといけないのと,RSSのXML解析時にいくつか警告が出るようです...
1
Import["http://ja.doukaku.org/feeds/comments/", "RSS"]

	
1
<?php readfile('http://ja.doukaku.org/feeds/comments/'); ?>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.io.*;
import java.net.*;

class MeApp
{
    public static void main(String[] args) throws Exception
    {
        final BufferedReader r = new BufferedReader(
            new InputStreamReader(
                new URL("http://ja.doukaku.org/feeds/comments/").openStream(), "UTF-8"));
        try
        {
            String s;

            while ((s = r.readLine()) != null)
            {
                System.out.println(s);
            }
        }
        finally
        {
            r.close();
        }
    }
}
gawkなのだぁ!
1
gawk 'BEGIN{while(("GET http://ja.doukaku.org/feeds/comments/ /inet/tcp/0/ja.doukaku.org/80" |& getline) > 0) {print $0}}'
Hackety Hack <http://hacketyhack.net/>
1
2
feed = Web.fetch("http://ja.doukaku.org/feeds/comments/")
puts feed
ソケットを使用しているので、一応Windowsでも似たようなコードで動くはず。 エラー処理していません。 あと、別のアドレスにアクセスしにいっている模様。なんでだろう。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char *request = "GET /feeds/comments/ HTTP/1.1\n\n";
    int sockfd;
    struct addrinfo hint;
    struct addrinfo *result;
    char buf[256];
    int size;

    /* アクセスしたいホストの情報を得る */
    memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;
    getaddrinfo("http://ja.doukaku.org", "80", &hint, &result);

    /* ソケットを作成し、接続しに行く */
    sockfd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    connect(sockfd, result->ai_addr, result->ai_addrlen);

    /* リクエストし、返ってくる文字列を表示 */
    write(sockfd, request, strlen(request));
    while (size = read(sockfd, buf, sizeof(buf))) {
        write(1, buf, size);
    }

    close(sockfd);
    return 0;
}
HTTP/1.1だとHostヘッダフィールドが必須です。指定しないと400エラーになります。これでホスト名を指定しないとバーチャルホストで動いているサイトから正しいデータが取れません。それ以前に、getaddrinfoにスキームを含めるとアドレス解決できないと思うのですが、最近のはできるの?
ultraistさんありがとうございます。 Hostヘッダフィールドを追加したら動きました。 getaddrinfoにスキームをつけるのはMac OS Xの方ではつけても問題ありませんでした。Ubuntuの方でやったらSegmentation fault (core dumped)がでました。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char *request = "GET /feeds/comments/ HTTP/1.1\nHost: ja.doukaku.org\n\n";
    int sockfd;
    struct addrinfo hint;
    struct addrinfo *result;
    char buf[256];
    int size;

    /* アクセスしたいホストの情報を得る */
    memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;
    getaddrinfo("ja.doukaku.org", "80", &hint, &result);

    /* ソケットを作成し、接続しに行く */
    sockfd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    connect(sockfd, result->ai_addr, result->ai_addrlen);

    /* リクエストし、返ってくる文字列を表示 */
    write(sockfd, request, strlen(request));
    while (size = read(sockfd, buf, sizeof(buf))) {
        write(1, buf, size);
    }

    close(sockfd);
    return 0;
}
コピーペースト失敗。 一行一行ごとに不要な空行できてしまった。
直しておきました。
ありがとうございます。
1
(url-http  (url-generic-parse-url  "http://ja.doukaku.org/feeds/comments/") #'display-buffer '(" *http ja.doukaku.org:80*"))
application/rss+xmlはバイナリとみなされるっぽいorz だから文字列ではなくてintegerのvectorが返る。
1
2
(require :drakma)
(format t "~a" (drakma:http-request "http://ja.doukaku.org/feeds/comments/" :force-binary nil))
download.fileを使うともっと簡単ですが・・・。
1
scan("http://ja.doukaku.org/feeds/comments/", what=character(0), sep="\n", encoding="UTF-8")
おやこっちを見落としてた。お題「XMLから情報を取り出す」の方に書いちゃいましたが…
1
2
(use rfc.http)
(values-ref (http-get "ja.doukaku.org" "/feeds/comments") 2)
もう一発Scala。
1
2
import scala.io._
println(Source.fromURL("http://www.google.co.jp").getLines.mkString(""))
初投稿です
1
ruby -e 'require "net/http"; require "kconv"; Kconv.toutf8(Net::HTTP.get_print("ja.doukaku.org", "/feeds/comments/"));'
あれれ、切れちゃった もう1回。。
1
2
ruby -e 'require "net/http"; require "kconv"; \
Kconv.toutf8(Net::HTTP.get_print("ja.doukaku.org", "/feeds/comments/"));'
PHP CLIで..
1
php -r 'echo file_get_contents("http://ja.doukaku.org/feeds/comments/");'
XMLHttpRequestは非同期通信(Ajax)だけでなく、シンプルでわかりやすい同期通信もさせられます。というわけで別解。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var url = "http://ja.doukaku.org/feeds/comments/";

function getxhr() {
  if (XMLHttpRequest) {
    var xhr = new XMLHttpRequest();
  } else if (ActiveXObject) {
    try {
      var xhr = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
      try {
        var xhr = new ActiveXObject("Microsoft.XMLHTTP");
      } catch(e) {
        var xhr = null;
      }
    }
  } else {
    var xhr = null;
  }
  return xhr;
}

function httpget(url) {
  var xhr = getxhr();
  if (xhr == null) return;

  xhr.open("GET", url, false);
  xhr.send(null);
  return xhr.responseText;
}

var data = httpget(url);
if (data) document.write(data);
Bash ってゆーか nc とゆーか。。。
1
2
3
4
5
http_get () {
  url="$1"
  host=$(echo $url | sed -e "s:[^/]*//::" -e "s:/.*::")
  echo -e "GET $url HTTP/1.0\n" | nc $host 80
}