Java - 连接到亚马逊

时间:2012-11-20 21:48:10

标签: java networking httpurlconnection urlconnection

我正在使用以下代码尝试通过亚马逊连接到关联计划:

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

课程会话和帐户都是我的,但它与我的问题无关。所以基本上我想连接到亚马逊网站,我遇到了问题。每当它打印出它实际写入的数据时,它看起来就像是在网页源中查看它的确切内容(用相关值写出正确的名称)。但是,当它打印出新的URL时,它与旧的URL相同。

我想我确实知道原因;看起来你在写之前就读不懂了(这就是我在初始化Scanner之前初始化BufferedWriter的原因,因为如果我不这样做,它会告诉我在读取之后无法写入并抛出IOException)基本上如果你查看网站的页面源代码,您将看到一个名为“sessionId”的ID,每次打开新连接时都会更改。

所以我只能得出结论,唯一的解决办法就是在写之前先找出要阅读的内容,以便会话ID不会改变。我得出结论是因为每次我创建一个新连接并打印出我正在编写的数据(在编码之前),会话ID就不同了。有没有人对如何做到这一点有任何想法?任何想法将不胜感激。感谢。

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

1 个答案:

答案 0 :(得分:1)

一个问题是:

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

将使用URL-escape替换所有的&符号和等号,所以不要发布这样的内容:

a=b&c=d&e=f

您发布的内容如下:

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

实际上是垃圾。

您需要分别对各个组件执行网址编码,然后将结果与=&汇总。