1

ユーザーに代わって Web サイトにログインし、HTML スクレイピングを行う必要があるアプリケーションを開発しています。他の多くの開発者と同様に、Cookie の管理に関しては、アプリ エンジンが問題を引き起こしています。私がログインしているサーバーは、最初の POST の後にリダイレクトを送信し、その後、別のリダイレクトを最終的なランディング ページに送信します。私が知る限り、その目的は、サーバーが Cookie が機能していることを確認することです。SOに関する他の回答から次のヘルパークラスをつなぎ合わせました。

public class Utilities {

    public static String smartPost(String url, String data) throws IOException {
        // storage for cookies between redirects
        Map<String, String> cookies = new HashMap<String, String>();

        HttpURLConnection connection;
        StringBuilder response = new StringBuilder();
        response.append(url);
        URL resource = new URL(url);
        connection = (HttpURLConnection) resource.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");

        connection.setRequestProperty("Content-Length",
                "" + Integer.toString(data.getBytes().length));
        connection.setRequestProperty("Content-Language", "en-US");

        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(false);
        connection.setDoInput(true);
        connection.setDoOutput(true);

        // Send request
        DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
        wr.writeBytes(data);
        wr.flush();
        wr.close();

        url = connection.getHeaderField("location");

        while (url != null) {
            // Get Cookies
            getCookiesFromConnection(connection, cookies);
            URL redirectResource = new URL(url);
            response.append(url);
            connection = (HttpURLConnection) redirectResource.openConnection();
            connection.setRequestMethod("GET");
            addCookiesToConnection(connection, cookies);
            connection.setInstanceFollowRedirects(false);

            connection.setUseCaches(false);
            connection.setDoInput(true);
            url = connection.getHeaderField("location");
            connection.disconnect();
        }

        // Arrived at final location
        InputStream is = connection.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        while ((line = rd.readLine()) != null) {
            response.append(line);
            response.append('\r');
        }
        rd.close();

        return response.toString();
    }

    static void addCookiesToConnection(HttpURLConnection c,
            Map<String, String> storage) {
        StringBuilder cookieStringBuilder = new StringBuilder();
        for (Entry<String, String> e : storage.entrySet()) {
            cookieStringBuilder.append(e.getKey());
            cookieStringBuilder.append("=");
            cookieStringBuilder.append(e.getValue());
            cookieStringBuilder.append(";");
        }
        c.setRequestProperty("Cookies", cookieStringBuilder.toString());
    }

    static void getCookiesFromConnection(HttpURLConnection c,
            Map<String, String> storage) {
        Map<String, List<String>> headers = c.getHeaderFields();
        for (Entry<String, List<String>> e : headers.entrySet()) {
            if (e.getKey().equalsIgnoreCase("Set-Cookie")) {
                for (String cookieHeader : e.getValue()) {
                    String cookie = cookieHeader.substring(0,
                            cookieHeader.indexOf(";"));
                    String key = cookie.substring(0, cookie.indexOf("="));
                    String value = cookie.substring(cookie.indexOf("=") + 1);
                    storage.put(key, value);
                }
            }
        }
    }
}

私の目標は、リダイレクトを手動で処理し、Cookie を最終ページに渡すことでした。開発サーバーでは問題なく動作しますが、コードが機能しているとは思いませんが、ローカル サーバーでの既定の動作です。運用サーバーでこの種の機能を実装した経験のある人はいますか? 私は java.net パッケージにかなり慣れていないので、解決策にはほど遠いかもしれません。

私はもともとこれをGoで実装しようとしましたが、同じ結果が得られ、Goの経験がまったく不足しているだけだと考えました. いずれにせよ、Jsoup のおかげで Java は html スクレイピングが簡単になりますが、私は Python を使用することに反対しません。これは大規模なプロジェクトのかなり小さな部分であり、私は切り替えるほど遠くにいるわけではありません。

4

1 に答える 1

0

これに数日間苦労した後 、Pythonで私がやろうとしていたことを正確に行うこの記事を見つけました。私はこのプロジェクトに Python を使用することに決め、HTML スクレイピングには BeautifulSoup を使用します。最初に私のコードの何が問題だったのかまだわかりません。

于 2012-12-28T19:58:40.520 に答える