我正在尝试通过https://www.nasdaq.com/symbol/aapl/historical获取200多种不同股票的10年历史每日价格的原始数据。我现在正在做的是搜索每个股票,从“时间范围”下拉菜单中选择“ 10年”,等待响应,然后单击底角的“以Excel格式下载此文件”。
显然,这是非常繁琐且耗时的,因此,我正在尝试查看是否有任何方法可以自动执行此操作。
我注意到“以Excel格式下载此文件”按钮调用了JS函数:
function getQuotes(download) {
if (!download)
showLoadingSpinner();
var data = $("[id$='ddlTimeFrame']").val();
var submitString = data + '|' + download + "|" + quoteBoxSelectedSymbol; if (!download) {
$.ajax({
type: "POST",
url: baseUrl,
data: submitString,
contentType: "application/json",
success: function (response) {
$("[id$='historicalContainer']").html(response);
$(".genTable tbody tr:odd").addClass("genTablealt");
hideLoadingSpinner();
}
});
}
else {
$("[id$='submitString']").val(submitString);
$("#getFile").submit();
}
}
download变量似乎是一个布尔值,当单击按钮时将其传递为true。有没有办法将函数生成的任何端点注入到Postman之类的东西中?我对JavaScript不太熟悉。
答案 0 :(得分:1)
您至少需要2个请求
1. GET request: to get the required cookies 2. POST request: to change timespan/ -> parse response / downlaod excel
GET /symbol/aapl/historical HTTP/1.1 Host: www.nasdaq.com cache-control: no-cache
测试
pm.test("valid response", function () {
pm.response.to.have.status(200);
pm.response.to.be.withBody;
pm.expect(pm.response.text()).to.include("Results for: ");
});
仅在下载excel时需要以下内容
pm.test("valid response", function () {
pm.response.to.have.status(200);
pm.response.to.be.withBody;
pm.expect(pm.response.text()).to.include("Results for: ");
});
POST /symbol/aapl/historical HTTP/1.1 Host: www.nasdaq.com x-requested-with: XMLHttpRequest content-type: application/json accept: */* cache-control: no-cache {{submitNoDownload}}
测试
// ... continue test code ...
var input = pm.response.text();
var regex = /"__VIEWSTATE" value="(.*?)"/;
var match = regex.exec(input);
if (match) pm.globals.set("__VIEWSTATE", match[1]);
var regex = /"__VIEWSTATEGENERATOR" value="(.*?)"/;
var match = regex.exec(input);
if (match) pm.globals.set("__VIEWSTATEGENERATOR", match[1]);
var regex = /"__VIEWSTATEENCRYPTED" value="(.*?)"/;
var match = regex.exec(input);
if (match) pm.globals.set("__VIEWSTATEENCRYPTED", match[1]);
var regex = /"__EVENTVALIDATION" value="(.*?)"/;
var match = regex.exec(input);
if (match) pm.globals.set("__EVENTVALIDATION", match[1]);
//-----
var regex = /<option value="(\d+[dmy])">10 Years<\/option>/;
var match = regex.exec(input);
if (match) var timeframe = match[1];
pm.globals.set("timeframe", timeframe);
//-----
var regex = /var quoteBoxSelectedSymbol="(.*?)";/;
var match = regex.exec(input);
if (match) var symbol = match[1];
pm.globals.set("symbol", symbol);
//-----
var submitNoDownload = timeframe + "|false|" + symbol;
pm.globals.set("submitNoDownload", submitNoDownload);
var submitToDownload = timeframe + "|true|" + symbol;
pm.globals.set("submitToDownload", submitToDownload);
// ... continue test code ...
var input = pm.response.text();
var regex = /"__VIEWSTATE" value="(.*?)"/;
var match = regex.exec(input);
if (match) pm.globals.set("__VIEWSTATE", match[1]);
var regex = /"__VIEWSTATEGENERATOR" value="(.*?)"/;
var match = regex.exec(input);
if (match) pm.globals.set("__VIEWSTATEGENERATOR", match[1]);
var regex = /"__VIEWSTATEENCRYPTED" value="(.*?)"/;
var match = regex.exec(input);
if (match) pm.globals.set("__VIEWSTATEENCRYPTED", match[1]);
var regex = /"__EVENTVALIDATION" value="(.*?)"/;
var match = regex.exec(input);
if (match) pm.globals.set("__EVENTVALIDATION", match[1]);
//-----
var regex = /<option value="(\d+[dmy])">10 Years<\/option>/;
var match = regex.exec(input);
if (match) var timeframe = match[1];
pm.globals.set("timeframe", timeframe);
//-----
var regex = /var quoteBoxSelectedSymbol="(.*?)";/;
var match = regex.exec(input);
if (match) var symbol = match[1];
pm.globals.set("symbol", symbol);
//-----
var submitNoDownload = timeframe + "|false|" + symbol;
pm.globals.set("submitNoDownload", submitNoDownload);
var submitToDownload = timeframe + "|true|" + symbol;
pm.globals.set("submitToDownload", submitToDownload);
第一件事!我们这里有什么..
pm.test("valid response", function () {
pm.response.to.have.status(200);
pm.response.to.be.withBody;
pm.expect(pm.response.text()).to.include("Results for: ");
});
var input = pm.response.text();
var regex = /<tr>\s+(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)<\/tr>/mg;
var match = regex.exec(input);
while (match != null) {
// Iterate thru all rows/data
pm.globals.set("date", match[1]);
pm.globals.set("open", match[2]);
pm.globals.set("high", match[3]);
pm.globals.set("low", match[4]);
pm.globals.set("close-last", match[5]);
pm.globals.set("volume", match[6]);
match = regex.exec(input);
}
上面的代码将选择以下html代码
pm.test("valid response", function () {
pm.response.to.have.status(200);
pm.response.to.be.withBody;
pm.expect(pm.response.text()).to.include("Results for: ");
});
var input = pm.response.text();
var regex = /<tr>\s+(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)(?:<td>\s+(\S+)\s+<\/td>\s+)<\/tr>/mg;
var match = regex.exec(input);
while (match != null) {
// Iterate thru all rows/data
pm.globals.set("date", match[1]);
pm.globals.set("open", match[2]);
pm.globals.set("high", match[3]);
pm.globals.set("low", match[4]);
pm.globals.set("close-last", match[5]);
pm.globals.set("volume", match[6]);
match = regex.exec(input);
}
html代码中的某个地方
var data = $("[id$='ddlTimeFrame']").val();
var submitString = data + '|' + download + "|" + quoteBoxSelectedSymbol;
var data = $("[id$='ddlTimeFrame']").val();
var submitString = data + '|' + download + "|" + quoteBoxSelectedSymbol;
quoteBoxSelectedSymbol = AAPL
submitString = 10y | true | AAPL
POST /symbol/aapl/historical HTTP/1.1 Host: www.nasdaq.com x-requested-with: XMLHttpRequest Content-Type: application/x-www-form-urlencoded accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 cache-control: no-cache __VIEWSTATE:{{__VIEWSTATE}} __VIEWSTATEGENERATOR:{{__VIEWSTATEGENERATOR}} __VIEWSTATEENCRYPTED:{{__VIEWSTATEENCRYPTED}} __EVENTVALIDATION:{{__EVENTVALIDATION}} ctl00$quotes_content_left$submitString:{{submitToDownload}}