iT邦幫忙

0

(已解決)JS整段貼上無法執行 分次貼上則可以?

  • 分享至 

  • xImage

目前我在F12裡面享用JS寫爬蟲 整個已經寫好 也算成功了
只是碰到一個小問題 程式碼如下

let space

let req=new XMLHttpRequest;
req.open("get","https://meteor.today/article/VCq8X3");
req.onload=function(){space=this.response};
req.send();

let parser = new DOMParser();
//目前下面這句子有問題 不知道為什麼不能一次發  這句要拆開發才能用
let parsed = parser.parseFromString(space, "text/html");
//----------------------

let text=parsed.getElementById("article_content")
let texted=text.innerText.split("\n")
for (i=0;i<texted.length;i++){
if(texted[i].search(".jpg")>-1){console.log(texted[i])};
}

如果我整段貼上 parsed得到的html就會抓不到body的內容(undefined)
如果我先貼一部分 然後再把下面那段貼上去
整個是可以執行的.... 想了解為什麼會這樣 該如何修正?

obarisk iT邦研究生 1 級 ‧ 2022-05-27 09:43:24 檢舉
看一下 fetch, async, await 或是用 fetch().then
greenriver iT邦研究生 4 級 ‧ 2022-05-27 10:33:52 檢舉
下面的那些code,要放在req.onload=function(){//放在這裡面}的樣子
謝謝各位~
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
featherm
iT邦新手 5 級 ‧ 2022-05-26 16:33:23
最佳解答

先講結論:
因為open發request預設是非同步的
send()之後程式就往下跑了 不會等你的回傳結果
要嘛改同步 要嘛程式寫onload裏面

建議自己了解一下同步與非同步 這邊舉個例子給你
假如你今天要面試 需要準備畢業證書、個人資料等等 此時你發現你的畢業證書不見了
因為你住得離你學校很遠 你不想親自跑回去辦法 想線上申請請學校寄過來
接下來你可以選擇等畢業證書寄到之後再處理其他事 或者不浪費時間先準備你的身分證影本
而這種“不等前一件事做完 讓他慢慢跑 先做下一件事”的過程就叫非同步
“一步一步慢慢做”的就是同步

為了避免因為response很慢導致整個流程卡住 送request才會預設為非同步執行

回到你的程式 因為你後續的動作是寫在外面的
整段貼上的話 送出request後程式直接往下跑 此時還沒有收到response space是空的 當然就什麼都parse不出來
分開貼上的話當你貼後半段程式的時候response已經回來了 space有東西 自然可以繼續執行

onload就是來處理這個問題的 onload會在response後才執行 你需要等待response後才執行的程式應該要寫在這裡面

謝謝大老 好清楚

0

你要先了解同步及非同步。還有閉包的特性。

樓上有給你說的很清楚了。我就不多說了。

謝謝您

0
greenriver
iT邦研究生 4 級 ‧ 2022-05-27 10:32:20

題外話,好玩修改了一下你的code。
互相分享一下

(async function webCrawler() {
    //let theDiv = document.createElement('div')
    let sent = await fetch('https://meteor.today/article/VCq8X3')
        .then(res =>  res.text())
        .catch(error => error)
    searchJpg(sent)
    //theDiv.innerText = sent
    //document.body.appendChild(theDiv)
})()

function searchJpg(pageTextString) {
    let parser = new DOMParser();
    let parsed = parser.parseFromString(pageTextString, "text/html");
    let text = parsed.getElementById("article_content")
    let texted = text.innerText.split("\n")
    for (i = 0; i < texted.length; i++) {
        if (texted[i].includes(".jpg")) {
            console.log('我是', i, texted[i])
        };
    }
}

這什麼感覺很屌欸~ 晚點試試看

我要發表回答

立即登入回答