2

次のコードを使用して、Amazonを介してアソシエイトプログラムに接続しようとしています。

    public static Session login(final Account account) throws IOException{
    final HashMap<String, String> info = new HashMap<String, String>();
    final URL url = new URL("https://affiliate-program.amazon.com/");
    final HttpURLConnection connection = (HttpURLConnection)(account.isProxySet() ? url.openConnection(account.getProxy()) : url.openConnection());
    connection.setUseCaches(false);
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setReadTimeout(timeout);
    connection.setConnectTimeout(timeout);
    connection.setRequestMethod("POST");
    connection.addRequestProperty("User-Agent", account.getUserAgent());
    connection.addRequestProperty("User-Content", "text/plain");
    connection.setAllowUserInteraction(true);
    final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
    final Scanner reader = new Scanner(connection.getInputStream());
    while(reader.hasNextLine()){
        final String line = reader.nextLine().trim();
        if(line.contains("<input type=\"hidden\"")){
            final String[] split = line.split("\"");
            info.put(split[3], split[5]);
        }
    }
    String writable = "";
    final Iterator<String> iterator = info.keySet().iterator();
    while(iterator.hasNext()){
        final String key = iterator.next();
        writable += String.format("%s=%s", URLEncoder.encode(key, "UTF-8"), URLEncoder.encode(info.get(key), "UTF-8"));
        if(iterator.hasNext()) writable += "&";
    }
    final String data = String.format("%s&email=%s&password=%s&submit=Sign In", writable, URLEncoder.encode(account.getEmail(), "UTF-8"), URLEncoder.encode(account.getPass(), "UTF-8"));
    System.out.println(data);
    writer.write(data);
    writer.flush();
    writer.close();
    connection.getInputStream().read();
    System.out.println(connection.getURL().toString());
    return new Session(account);
}

セッションとアカウントのクラスはどちらも私のものですが、私の問題とは関係ありません。だから基本的に私はアマゾンサイトに接続しようとしていますが、問題があります。実際に書き込んでいるデータを出力するときはいつでも、Webページのソース内でどのように見えるかを正確に示しているように見えます(適切な名前とそれに関連する値を書き込んでいます)。ただし、新しいURLを出力する場合は、古いURLと同じです。

私はその理由を知っていると思います。書き込む前に読み取ることができないようです(そのため、スキャナーを初期化する前にBufferedWriterを初期化しました。そうしないと、読み取り後に書き込みができず、IOExceptionがスローされるためです)。サイトのページソースを見ると、「sessionId」というIDが表示され、新しい接続を開くたびに変更されます。

したがって、唯一の解決策は、セッションIDが変更されないように、書き込む前に何らかの方法で読み取ることを見つけることであると結論付けることしかできませんでした。新しい接続を作成し、(エンコードされる前に)書き込んでいるデータを出力するたびに、セッションIDが異なるため、これを結論付けます。誰かがこれを行う方法について何かアイデアがありますか?任意のアイデアをいただければ幸いです。ありがとう。

編集:ruakhの答えに従ってコードを変更しました。

4

1 に答える 1

1

1つの問題はこれです:

    writer.write(URLEncoder.encode(data, "UTF-8"));

すべてのアンパサンドと等号をURLエスケープに置き換えるため、次のように投稿する代わりに、次のようにします。

a=b&c=d&e=f

あなたはこのようなものを投稿しています:

a%3Db%26c%3Dd%26e%3Df

これは事実上ゴミです。

個々のコンポーネントで個別にURLエンコードを実行してから、とを使用して結果をアセンブルする必要あり=ます&

于 2012-11-20T22:02:17.867 に答える