質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

6612閲覧

Jsoupでログイン後の専用ページにあるformを模倣してPOSTしてもデータが更新されない

risaito74

総合スコア44

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1グッド

1クリップ

投稿2016/11/21 09:42

編集2016/11/22 01:34

JsoupでTwitterにログインしてツイート取得
以前教えていただいたこちらのサイトを参考に、JsoupでログインしてformデータをPOST更新するプログラムを作成しています。
ログインして、ログイン後の各ページへ遷移してページのHTMLを取得することまではできました。
該当ページのformデータを抽出して、任意のデータを変更し、POSTしてデータを更新したいのですが、POSTがうまく実行できず、データが反映されません。

Java

1 2 String ua = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36 "; 3 4 // ログイン画面取得 5 Response res1 = Jsoup.connect("http://(とあるサイト)/") 6 .userAgent(ua) 7 .timeout(0) 8 .execute(); 9 10 Document doc = res1.parse(); 11 //System.out.println(doc); 12 13 //ログインPOST実行 14 Response res2 = Jsoup.connect("http://(ログイン用URL)") 15 .userAgent(ua) 16 .timeout(0) 17 .cookies(res1.cookies()) 18 .data("txt_account", "(ID)") 19 .data("txt_password", "(パスワード)") 20 .data("chk_save", "") 21 .data("login", "ログイン") 22 .method(Method.POST) 23 .execute(); 24 25 // イベント更新ページの表示 26 Response res3 = Jsoup.connect("http://(イベント登録用ページ)") 27 .userAgent(ua) 28 .timeout(0) 29 .cookies(res2.cookies()) 30 .method(Method.GET) 31 .execute(); 32 33 doc = res3.parse(); 34 35 //***** イベント更新用form情報の取得 ***** 36 Elements elements = new Elements(); 37 38 //***** start_yearの取得 ***** 39 elements = doc.getElementsByAttributeValue("name","start_year"); 40 String startYear = new String(); 41 for (Element element : elements) { 42 //System.out.println(element.outerHtml()); 43 startYear = element.outerHtml(); 44 } 45 //正規表現で「value=\"....\" selected」を検索 46 startYear = getPatternMatchFind(startYear,"value=\"....\" selected"); 47 //valueの抽出(前後の切り落とし) 48 startYear = getSplitFrontBack(startYear, "value=\"", "\" selected"); 49 //post形式に整形 50 startYear = "start_year=" + startYear; 51 System.out.println(startYear); 52 53 //***** start_monthの取得 ***** 54 elements = doc.getElementsByAttributeValue("name","start_month"); 55 String startMonth = new String(); 56 for (Element element : elements) { 57 //System.out.println(element.outerHtml()); 58 startMonth = element.outerHtml(); 59 } 60 //正規表現で「value=\"..\" selected」を検索 61 startMonth = getPatternMatchFind(startMonth,"value=\"..\" selected"); 62 //valueの抽出(前後の切り落とし) 63 startMonth = getSplitFrontBack(startMonth, "value=\"", "\" selected"); 64 //post形式に整形 65 startMonth = "start_month=" + startMonth; 66 System.out.println(startMonth); 67 68/***** 中略 *****/ 69 70 //***** イベントデータ更新POST ***** 71 Response res4 = Jsoup.connect("http://(POSTするURL)") 72 .userAgent(ua) 73 .timeout(0) 74 .cookies(res2.cookies()) 75 .data("start_year", startYear) 76 .data("start_month", startMonth) 77 .data("start_day", startDay) 78 /***** (残りのdataは省略) *****/ 79 .followRedirects(false) 80 .method(Method.POST) 81 .execute(); 82 83 doc = res4.parse(); 84 System.out.println(doc); 85 86 //POST後の更新ページをGET 87 Response res5 = Jsoup.connect("http://(イベント登録用ページ)") 88 .userAgent(ua) 89 .timeout(0) 90 .cookies(res2.cookies()) 91 .method(Method.GET) 92 .execute(); 93 94 doc = res5.parse(); 95 System.out.println(doc); 96 97

res4.parse()の出力結果は空のhtmlになっています。このことからPOST処理が失敗しているのではないかと考えています。
また、正しくPOSTできていればres5.parse()の出力結果で変更後のデータが確認できるはずですが、変更はされていませんでした。
(念のためブラウザから手動ログインでも確認しましたが、データは更新されていませんでした)

POSTする各属性と値(name=value)について抜けはないか?nameの表記ミスはないか?この点は確認しました。

このプログラムでPOSTが失敗する原因と対策について、ご助言いただけないでしょうか?
よろしくお願いいたします。

A-pZ👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

すみません、単純な勘違い・ミスでした!
.data("start_year", startYear)
において変数startYearの値を"start_year=2016"としていますが、ここが間違いで、data()の第二引数に入れる値は「value値のみ」でした。
したがって、上記プログラムでは"start_year=start_year=2016"がPOSTされてしまうため、エラーとなっていました。
startYearの値を"2016"とし、他のPOST用変数も同様に修正したところ、無事問題なくPOSTによるデータ登録ができました!
ご協力ご助言いただいた皆様、ありがとうございました!

投稿2016/11/22 08:44

risaito74

総合スコア44

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

POSTのサンプルは、下記のサイトが参考になるかと思います。

http://t-horikiri.hatenablog.jp/entry/20120308/1331182734

Timeout(0)が厳しいかと思いますので、下記で試してみてはいかがでしょうか?

.timeout(10 * 1000)

投稿2016/11/21 12:00

nagaetty

総合スコア1106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

risaito74

2016/11/21 12:33

助言ありがとうございます!明日職場で試してみたいと思います! なお、下記Jsoupサイトには「A timeout of zero is treated as an infinite timeout.」とあるのでtimeout(0)は無制限で待ってくれるのかと思っていましたが、まずは試してみたいと思います。 https://jsoup.org/apidocs/org/jsoup/Connection.html#timeout-int-
nagaetty

2016/11/21 12:49

ご指摘の通り無制限かもしれません。 後は、cookiesの値で状態管理している可能性があるので正しいcookiesの値を返却しているかご確認ください。わかりやすいのは、wiresharkというツールでサーバとのIN/OUTを確認して、ブラウザと作成したプログラムで比較するというのが一番良かったりします。(ただしSSLだと無理ですが)
risaito74

2016/11/21 13:49

度々ありがとうございます!cookiesも確認してみたいと思います。
risaito74

2016/11/22 01:41

ご助言いただいたtimeout(10 * 1000)など、タイムアウト時間を多めに設定してみましたが、こちらは挙動に変化はありませんでした。 また、各resのcookiesを確認してみたところ、ログイン処理時のres2のみクッキーにid,パス、セッションIDが入っていることがわかりました。こちらはres2のクッキーを使わなければステートフルにはならないということが理解できました。ありがとうございます! 問題の解決には至っていませんが、引き続き調べていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問