想抓的資料來源
https://wwwfile.megabank.com.tw/other/bulletin02_09.asp
因有需求想抓取上述資料來源的匯率,原先認為抓取每日結匯的匯率資料
http://rate.megabank.com.tw/bulletin02_02.asp ,(抓這個沒問題)
但它的結匯的數據並不等於歷史匯率數據,此時已經霧裡看花了....
藉由想取得的資料來源進行來源查找(F12查得另一資料來源),得到了下列網址
https://ebank.megabank.com.tw/global2/rs/rs03/PRS3001.faces
分析後得知網址需先取得ptoken= & javax.faces.ViewState= 的值(這部份也完成了),
但仍然不能取得歷史匯率資料,我有試著先手動開啟網頁查詢一次,並且不關視窗,就可以取得資料,是否還有漏了什麼動作或有什麼機制使得資料無法自動截取呢?
請各位先進指教一下,謝謝。
<?php
include('simple_html_dom.php');
// get DOM from URL or file
//$base = 'https://wwwfile.megabank.com.tw/other/bulletin02_09.asp';
$base = "https://ebank.megabank.com.tw/global2/rs/rs03/PRS3001.faces";
$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_URL, $base);
curl_setopt($curl, CURLOPT_REFERER, $base);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
$str = curl_exec($curl);
curl_close($curl);
// Create a DOM object
$html = new simple_html_dom();
// Load HTML from a string
$html->load($str);
// Get ptoken & javax.faces.ViewState
preg_match_all ('/action="(.*)"/U', $html, $pat_array);
$textFieldValue = $html->find('[id="javax.faces.ViewState"]',0)->value;
// NewURL
$newurl="https://ebank.megabank.com.tw".$pat_array[1][0]."&main=main&main%3Acurrency=03&typeGrp=LST&main%3AstartDate=2019%2F05%2F27&main%3AendDate=2019%2F05%2F31&main%3AdownloadType=TEXT&autoDisabled%3Amain%3Aj_id31=AutoDisabled%3AClicked&submitTrigger=&autoDisabled%3Amain%3AfileDownload=&autoDisabled%3Amain%3Aj_id32=&main%3Ahidstartdate=&main%3Ahidenddate=&javax.faces.ViewState=".$textFieldValue;
echo $newurl;
?>
我把 header 跟 form data
都塞到 postman 也是無法
可能是有什麼防範機制吧
不過他看起來沒有用 captcha 來防
就懶得去研究了
直接用最近在玩的 Puppeteer 來爬
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://ebank.megabank.com.tw/global2/rs/rs03/PRS3000.faces');
const dropDown = await page.select('#main\\:currency', '01');
const searchBtn = await page.click('#main\\:j_id31');
await page.waitForNavigation();
const header = await page.evaluate(() => {
const tds = Array.from(document.querySelectorAll('.head_td'));
return tds.map(td => td.innerHTML.trim());
});
const values = await page.evaluate(() => {
const tds = Array.from(document.querySelectorAll('.con_td'));
return tds.map(td => td.innerHTML.trim());
});
const result = header
.map((data, index) => { return { title: header[index], value: values[index]}})
.filter((data) => data.title !== '');
console.log(result);
await browser.close();
})();
Result
[ { title: '幣 別', value: '美金[USD]' },
{ title: '查詢起日', value: '2019/06/01' },
{ title: '查詢迄日', value: '2019/06/03' },
{ title: '日期', value: '2019/06/03' },
{ title: '即期買匯', value: '31.4400' },
{ title: '現金買匯', value: '31.1000' },
{ title: '即期賣匯', value: '31.5400' },
{ title: '現金賣匯', value: '31.7700' } ]
以上是用 node.js
php好像也有相關套件能用
稍微改一下應該就可以了
真給力,就把這些RUN一遍。
輸入日期我使用page.type會有錯誤,是我的認知有誤嗎?
await page.type('#main\\:startDate', '2019/06/03');
await page.type('#main\\:endDate', '2019/06/03');
他是用 querySelector
所以:那邊要兩個 \ 唷
另外剛試了一下
如果要輸入日期
還要先把 input 清空
跟一般操作一樣
await page.evaluate( () => {
document.getElementById("main:startDate").value = '';
document.getElementById("main:endDate").value = '';
});
const enterStartDate = await page.type('#main\\:startDate', '2019/06/03');
const enterEndDate = await page.type('#main\\:endDate', '2019/06/03');
可以用 page.screenshot 來擷取操作dom的情況
await page.screenshot({path: 'screenshot.png'});
其實只要先抓
https://wwwfile.megabank.com.tw/other/bulletin02_09.asp
取得Cookie之後,
就算不用post改用get也能正確抓資料了
https://ebank.megabank.com.tw/global2/rs/rs03/PRS3000.faces?main=main&main%3Acurrency=39&typeGrp=LST&main%3AstartDate=2019%2F06%2F01&main%3AendDate=2019%2F06%2F04&main%3AdownloadType=TEXT&autoDisabled%3Amain%3Aj_id31=AutoDisabled%3AClicked&submitTrigger=&autoDisabled%3Amain%3AfileDownload=&autoDisabled%3Amain%3Aj_id32=&main%3Ahidstartdate=&main%3Ahidenddate=&javax.faces.ViewState=_id33425
之後相同Cookie狀態下任意改連結參數都能正確取回資料
currency=39 人民幣
currency=01 美金
開始日期2019/05/01
startDate=2019%2F05%2F01
結束日期2019/05/31
endDate=2019%2F05%2F31