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

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

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

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

0回答

148閲覧

GASでのログインが必要な動的ページのスクレイピング

pilotak

総合スコア0

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2024/03/20 16:57

実現したいこと

電力会社の使用状況照会ページから自動でスクレイピングを行い、
Googleスプレッドシートにデータを転記したいと考えています。

発生している問題・分からないこと

ログインは突破できたものの取得したcontentにデータが含まれず、
また、ブラウザでは同URLでグラフと一覧表示の切り替えができることから
動的サイトかと思われます。

そのためPhantomJsCloud経由でスクレイピングをしようとしていますが、
エラーが発生してしまいデータを取得できません。
解決策をご教示いただけないでしょうか?

以下エラー内容

Exception: Limit Exceeded: URLFetch URL Length.
login @ 自動取得.gs:138

該当のソースコード

GAS

1class CookieUtil { 2 /* 3 Cookieデータから指定されたキーに対応する値を取得する 4 @param {string} cookies Cookieデータ("name=value;...") 5 @param {string} key 取得したいCookieのキー 6 @return {string} 指定されたキーに対応する値。見つからない場合は代替メッセージを返す。 7 */ 8 static getValue(cookies, key) { 9 10 // Cookieデータをセミコロンで分割し、各Cookieのキーと値のペアを取得する 11 const cookiesArray = cookies.split('; '); 12 13 // 各Cookieのキーと値のペアに対してループを行う 14 for (const c of cookiesArray) { 15 // キーと値のペアをイコールで分割する 16 const cArray = c.split('='); 17 18 // キーが指定されたキーと一致する場合、対応する値を返す 19 if (cArray[0] == key) { 20 return cArray[1]; 21 } 22 } 23 24 // 指定されたキーに対応する値が見つからない場合、代替メッセージを返す 25 return "値が見つかりませんでした"; 26 } 27} 28 29 30function login() { 31 32 // ログインページを開く(GET) 33 const loginURL = 'https://www.e-site.kyuden.co.jp/oksite/' 34 35 // リクエスト送信 36 let response = UrlFetchApp.fetch(loginURL) 37 38 // レスポンスヘッダーからCookieを取得 39 let cookies = response.getAllHeaders()["Set-Cookie"]; 40 cookies = cookies + ""; 41 42 Logger.log('取得したクッキー:\n' + cookies) 43 44 /* cookies = []; 45 46 if (typeof cookies["Set-Cookie"] !== 'undefined') { 47 // Set-Cookieヘッダーが2つ以上の場合はcookies['Set-Cookie']の中身は配列 48 cookies = typeof cookies["Set-Cookie"] == 'string' ? [cookies['Set-Cookie']] : cookies['Set-Cookie']; 49 for (var i = 0; i < cookies.length; i++) { 50 // Set-Cookieヘッダーからname=valueだけ取り出し、セミコロン以降の属性は除外する 51 cookies[i] = cookies[i].split(';')[0]; 52 }; 53 } 54 cookie = cookies.replace("JSESSIONID=", ""); 55 */ 56 57 // CookieからJSESSIONIDとBIGipServerEigyoKodai_PooLを取得 58 let cookie_JSESSIONID = CookieUtil.getValue(cookies, 'JSESSIONID') 59 let cookie_BSEKP = CookieUtil.getValue(cookies, 'HttpOnly,BIGipServerEigyoKodai_PooL') 60 61 Logger.log('クッキー JSESSIONIDの値:\n' + cookie_JSESSIONID); 62 Logger.log('クッキー BIGipServerEigyoKodai_PooLの値:\n' + cookie_BSEKP); 63 64 // コンテンツ(ログインページのHTML)を取得 65 let content = response.getContentText("UTF-8") 66 67 // Cheerioライブラリを使用し、ログインページのHTML情報からtokenを取得 68 let $ = Cheerio.load(content) 69 70 // 以下のパラメータはログインフォーム内に記載されているため取得 71 const attention = $('[name="attention"]').val() 72 const title = $('[name="title"]').val() 73 const desc = $('[name="desc"]').val() 74 75 // ログインフォーム送信(POST) 76 // リクエストヘッダー(cookieとuser-agent) 77 let headers = { 78 'cookie': 'JSESSIONID=' + cookie_JSESSIONID + '; ' + 'BIGipServerEigyoKodai_PooL=' + cookie_BSEKP, 79 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36' 80 } 81 82 // リクエストデータ(token+ログイン情報) 83 let payload = { 84 'loginId': 'loginId', 85 'password': 'password', 86 'attention': attention, 87 'title': title, 88 'desc': desc 89 } 90 91 // ヘッダー・リクエストデータをセット 92 let options = { 93 'method': 'post', // POSTメソッド 94 'headers': headers, 95 'payload': payload, 96 'followRedirects': true // リダイレクト処理を抑止しておく 97 }; 98 99 // リクエスト送信 100 response = UrlFetchApp.fetch('https://www.e-site.kyuden.co.jp/oksite/login/EPHW0010', options) 101 content = response.getContentText("UTF-8") 102 103 // 結果の確認 104 Logger.log("初回のアクセス:" + response.getResponseCode()) 105 //Logger.log(content) 106 107 // データを取得したいページのURL 108 let targetURL = "https://www.e-site.kyuden.co.jp/oksite/login/EPHW0310" 109 110 // 先ほどと同じoptionsを使用しURLからデータを取得 111 response = UrlFetchApp.fetch(targetURL, options) 112 content = response.getContentText("UTF-8") 113 114 Logger.log("目的ページへのアクセス:" + response.getResponseCode()) 115 116 $ = Cheerio.load(content); 117 118 // trの中身が取れているかを確認 119 if ($('tbody tr').length > 0) { 120 // 要素が取れている:成功 121 console.log("取得:" + '成功') 122 } else { 123 // 要素が取れていない:失敗 124 console.log("取得:" + '失敗') 125 } 126 127 //スクリプトプロパティからPhantomJsCloudのAPIキーを取得する 128 let key = PropertiesService.getScriptProperties().getProperty('PHANTOMJSCLOUD_ID'); 129 130 //オプション項目をJSONにしてペイロードとして定義し、エンコードする 131 payload = JSON.stringify(options); 132 let payload2 = encodeURIComponent(payload); 133 134 //PhantomJsCloudのAPIリクエストを行うためのURLを設定 135 let apiUrl = "https://phantomjscloud.com/api/browser/v2/" + key + "/?request=" + payload2; 136 137 //設定したAPIリクエスト用URLにフェッチして、情報を取得する。 138 response = UrlFetchApp.fetch(apiUrl); 139 140 //取得したjsonデータを配列データとして格納 141 let json = JSON.parse(response.getContentText()); 142 143 //APIから取得したデータからJSから生成されたソースコードを取得 144 let source = json["content"]["data"]; 145 return source; 146}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

エラーを検索したところ

引用テキスト回避策としてHTTP/GETではなく、HTTP/POSTに切り替える

とのことでしたが、optionsのmethodは既にpostなので対応に行き詰まっています。

補足

特になし

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

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

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

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

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

poto568

2024/03/21 00:31

> Limit Exceeded: URLFetch URL Length. と言われているので、135行目で作った apiUrl の中身を 表示してみると問題の切り分けになるかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問