iT邦幫忙

0

javascript: xmlHttp.open

我有url1和url2兩個連結,url1是一個股票網站,url2是我直接把url1的page source複製而成的。
當我用.open連去url2時,所有程式都正常運作,readyState==4、status==200、也能讀到respenseText.
但當我連去url1時,status就會==0,respenseText也會空白一片。
請問是哪裡出問題了呢?

function sendRequest(order){
	xmlHttp = new XMLHttpRequest();
	xmlHttp.onreadystatechange = function(){
		catchResult(order);
	}
	var id = eval('form1.stock' + order + '.value');
	var url1 = 'http://www.etnet.com.hk/www/tc/stocks/realtime/quote.php?code=00005'+new Date().getTime();	
	var url2 = 'systematic.htm?timeStamp='+new Date().getTime();
	xmlHttp.open('GET',url1,true);
	xmlHttp.send(null);
	window.status = 'Checking Value...';
}
	
function catchResult(order){
	if (xmlHttp.readyState == 4){
		if (xmlHttp.status == 200) {
			alert(xmlHttp.status);
			alert(xmlHttp.responseText);
			
			alert('if (xml.indexOf('<title>')>=0){');
			start1 = xml.indexOf('<title>') + 7;
			end1 = xml.indexOf(' - 免費即時股票報價');
			output1 = xml.slice(start1, end1);
			start2 = xml.indexOf('<title>') + 7;
			end2 = xml.indexOf(' - 免費即時股票報價');
			output2 = xml.slice(start2, end2);
			eval('result' + order).innerHTML = "<h3>" + output1 +" "+ output2 + "</h3>";	
		} else {
			alert(xmlHttp.status);
			alert(xmlHttp.responseText);
			eval('result' + order).innerHTML = "<h3>股票號碼錯誤!</h3>";
			}
		}
		window.status = '';
	}

附上一些課堂的資料。紅、藍、綠色的是我自己加的註解,可以忽略。
https://ithelp.ithome.com.tw/upload/images/20190921/201198157EReenJKPV.pnghttps://ithelp.ithome.com.tw/upload/images/20190921/20119815P7laJ7uKNU.png

看更多先前的討論...收起先前的討論...
ccutmis iT邦高手 8 級 ‧ 2019-09-21 17:14:34 檢舉
url1是外網 url2是本地端的網頁 看看是不是跟這個原因類似,
https://ithelp.ithome.com.tw/questions/10195351
dragonH iT邦超人 6 級 ‧ 2019-09-21 17:32:40 檢舉
第二個 function 怎麼突然蹦出來 xml 跟 xmlHttp
hypons iT邦新手 5 級 ‧ 2019-09-21 18:26:13 檢舉
如果是的話那應該怎樣寫才對呢? 因為我連看也看不懂那個例子。。。 抱歉。。
dragonH iT邦超人 6 級 ‧ 2019-09-21 19:30:08 檢舉
一步一步來

先想辦法拿到你要的資料

因為我很懷疑

你只用一個 get

真的就能拿到你要的資料嗎
hypons iT邦新手 5 級 ‧ 2019-09-21 20:05:46 檢舉
看課堂的影片就是這樣就成功了,不過那影片好像是2004年的....
hypons iT邦新手 5 級 ‧ 2019-09-21 20:07:38 檢舉
所以怎樣才知道是不是跨域 api的問題呢? 如果是的話那應該是要在後端解決嗎?
dragonH iT邦超人 6 級 ‧ 2019-09-21 20:40:57 檢舉
2004 年的東西應該差蠻多的

爬蟲很少單用前端做的
Han iT邦新手 4 級 ‧ 2019-09-21 20:50:30 檢舉
// 所以怎樣才知道是不是跨域 api的問題呢? 如果是的話那應該是要在後端解決嗎?

用瀏覽器打開f12開發者工具,裡面會有錯誤訊息
hypons iT邦新手 5 級 ‧ 2019-09-21 20:53:28 檢舉
我現時的理解是在影片中他進入的網站是准許爬蟲存取的,所以他就成功了。
但我現在去的網站都不准,所以就在xmlHttp.status == 200被擋住了,是這樣嗎?
dragonH iT邦超人 6 級 ‧ 2019-09-21 21:07:52 檢舉
造成你失敗的原因可能不只一個

我底下補充了一種方法

1 個回答

1
dragonH
iT邦超人 6 級 ‧ 2019-09-21 21:02:47

大概說一下爬蟲基本的步驟

首先

打開你的 browser console (f12)

找到你想爬的網站的 resource url

確認你要的資料

確實是從這 url 來的

e.g.

我想要找 60.000

也就是買入價格

https://ithelp.ithome.com.tw/upload/images/20190921/20117259anYmlTnWW6.png

確認好後

把這 url 整個 header copy 下來貼到 postman 上

https://ithelp.ithome.com.tw/upload/images/20190921/20117259VOR40FzfYz.png

如果這個 url 是用 post 之類的 method

則須注意他 post 出去的 data

然後開始過濾 header

確認哪一些 header 是必要的

也就是沒送哪個 header 會拿不到 data

img

最後會發現

只有

Referer: ' http://www.etnet.com.hk/www/tc/stocks/realtime/quote.php'

這個 header 是必須的

然後就開始寫 code

隨便一種語言都可以

const axios = require('axios').default;
const cheerio = require('cheerio');
const url = 'http://www.etnet.com.hk/www/tc/stocks/realtime/quote.php?code=00005';
(async () => {
  const config = {
    headers: 
    { 
      Referer: 'http://www.etnet.com.hk/www/tc/stocks/realtime/quote.php?code=00005'
    },
  };
  const data = await axios.post(url, {}, config)
    .then((res) => {
      return res.data
    });
  const $ = cheerio.load(data);
  $('#StkList > ul > li').each((index, el) => {
    console.log($(el).text().trim());
  });
})()

最後可以得到結果

買入 #
60.000
10天平均值
59.660
賣出 #
60.050
20天平均值
58.093
交易宗數
2512
50天平均值
59.829
每宗成交金額
312,929
100天平均值
62.164
加權平均價
60.148
250天平均值
62.537
交易貨幣
HKD
52周高
68.940
單位
400
52周低
55.300
每手入場費
24,000
14天RSI
55.614
買賣差價
0.050/0.050
10天回報率i
3.627%
市盈率/預期
12.166/11.423
風險率i
2.431%
周息率/預期
6.634/6.641
回報/風險比率i
1.492
每股盈利
USD 0.630
啤打系數i
+0.731
每股全年派息
USD 0.510
上市日期
--
每股帳面淨值
USD 9.148
上市價
--
收市競價證券i
是
市調機制證券i
是

以上

ps.

貼到 postman

一方面是為了過濾 header

一方面是測這個頁面是不是用 js render 的

是用 js render 的話

又是另一個故事了/images/emoticon/emoticon11.gif

看更多先前的回應...收起先前的回應...
hypons iT邦新手 5 級 ‧ 2019-09-21 21:10:58 檢舉

謝謝,我明天會試試看。過期的課讓我有點被騙的感覺...
請問你是用甚麼software寫code的呢?課堂教的是dreamweaver,好像大家都沒有在用。 而且不知為什麼用不到console.log()

dragonH iT邦超人 6 級 ‧ 2019-09-21 21:15:18 檢舉

hypons

請問你是用甚麼software寫code的呢?

我是用 vscode 寫的

免費好用

課堂教的是dreamweaver,好像大家都沒有在用

dreamweaver 丟了吧(誤

個人覺得有點過時的產品

過期的課讓我有點被騙的感覺...

你這課

不會是用買的吧.../images/emoticon/emoticon21.gif

而且不知為什麼用不到console.log()

不是很懂你的意思

hypons iT邦新手 5 級 ‧ 2019-09-21 21:28:52 檢舉

對...用買的... 我是香港來的,這邊沒有很多學coding的選擇...本來說先上了課,有基本概念後再算。 現在發覺真的不行....

我在dreamweaver執行concole.log("abc"); 沒有反應/images/emoticon/emoticon10.gif

dragonH iT邦超人 6 級 ‧ 2019-09-21 21:35:36 檢舉

hypons

網路上有很多資源呀

Coursera

Udemy

都不錯

鐵人賽

也有很多好文章可以參考

我在dreamweaver執行concole.log("abc"); 沒有反應

沒反應可能有幾種情況

1 .

你 coding 時也打錯字 concole.log ≠ console.log /images/emoticon/emoticon01.gif

2 .

你的程式還沒執行到那就中斷了

3 .

你的程式根本不會執行到那部分

hypons iT邦新手 5 級 ‧ 2019-09-21 21:38:30 檢舉

我剛下載了vscode~ 喔 那個只是concole.log只是在這裡留言時打錯了啦~~ hahha

我要發表回答

立即登入回答