実現したいこと
電力会社の使用状況照会ページから自動でスクレイピングを行い、
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なので対応に行き詰まっています。
補足
特になし
あなたの回答
tips
プレビュー