2

我正在使用以下代码尝试通过 Amazon 连接到 associates 程序:

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

课程 Session 和 Account 都是我的,但它与我的问题无关。所以基本上我正在尝试连接到亚马逊网站,但我遇到了问题。每当它打印出它实际写入的数据时,它似乎看起来就像它在网页源内部的样子(用它们的关联值编写正确的名称)。但是,当它打印出新 URL 时,它与旧 URL 相同。

我想我确实知道原因;看来您在写入之前无法阅读(这就是为什么我在初始化 Scanner 之前初始化 BufferedWriter 因为如果我没有,它会告诉我阅读后我无法写入并抛出 IOException)基本上如果你查看该站点的页面源,您会看到一个名为“sessionId”的 id,每次打开新连接时它都会更改。

所以我只能得出结论,唯一的解决方案是在写作之前找出某种方式来阅读,这样会话ID就不会改变。我得出这个结论是因为每次我创建一个新连接并打印出我正在写入的数据(在它被编码之前),会话 ID 都是不同的。有人对如何做到这一点有任何想法吗?任何想法将不胜感激。谢谢。

编辑:根据 ruakh 的回答修改了代码。

4

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 回答