Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
I would like to download the old-time radio show I Love a Mystery from the OTRR website. I figured out how to construct the list of right URLs, const urlStub = "https://otrr.org/OTRRLibrary/jukebo...
Question
javascript
#4: Post edited
- I would like to download the old-time radio show [I Love a Mystery](https://www.otrr.org/OTRRLibrary/otrrlibrary.html?idp=4919) from the OTRR website. I figured out how to construct the list of right URLs,
- ```javascript
- const urlStub = "https://otrr.org/OTRRLibrary/jukebox/";
- copy(Array.from(
- document.getElementsByTagName('a')).
- map( a => `"${urlStub}${a.href.split('/').pop()}"` ).
- join(' ')
- )
- ```
- but when I call it with `curl`,
- ```bash
- for url in <copied-list>; do curl -k -O $url; done
- ```
I get a lot of `404 Not Found`. I realized that clicking on the titles will load a player on the page "pre-loading" the audio file, and then I can use `curl`. It is quite a chore to go through hundreds of files though, so I figured I would make it a bit easier by collecting the "title" elements, and click them one by one until it errors out,- ```javascript
- const t = Array.from(document.querySelectorAll('td.colTitle'));
- t.pop().click()
- ...
- t.pop().click()
- ```
- but this is still not the best.
- ### The solution thus far
- I cobbled together the snippet below that uses [`MutationObserver`][2] recursively, based on the SO threads below, but I assume that there is a simpler solution (and one that doesn't potentially run out of memory on a page with thousands of episodes).
- + `stackoverflow` [javascript - How to wait until an element exists?](https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists)
- + `stackoverflow` [javascript - How to check if an element has been loaded on a page before running a script?](https://stackoverflow.com/questions/34863788/how-to-check-if-an-element-has-been-loaded-on-a-page-before-running-a-script)
- It seems to get to job done, but the `Promise` will always remain `pending` and it feels very hacky:
- ```javascript
- function waitForElement(querySelector, elemArr) {
- return new Promise((resolve, reject) => {
- if (elemArr.length) {
- console.log(elemArr);
- elemArr.pop().click();
- } else {
- return resolve();
- }
- if (document.querySelectorAll(querySelector).length) {
- waitForElement(querySelector, elemArr);
- }
- const observer = new MutationObserver( () => {
- if (document.querySelectorAll(querySelector).length) {
- observer.disconnect();
- waitForElement(querySelector, elemArr);
- }
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true
- });
- });
- }
- t = Array.from(document.querySelectorAll('td.colTitle'))
- waitForElement("audio", t)
- ```
- [1]: https://i.stack.imgur.com/LTAKW.gif
- [2]: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
- I would like to download the old-time radio show [I Love a Mystery](https://www.otrr.org/OTRRLibrary/otrrlibrary.html?idp=4919) from the OTRR website. I figured out how to construct the list of right URLs,
- ```javascript
- const urlStub = "https://otrr.org/OTRRLibrary/jukebox/";
- copy(Array.from(
- document.getElementsByTagName('a')).
- map( a => `"${urlStub}${a.href.split('/').pop()}"` ).
- join(' ')
- )
- ```
- but when I call it with `curl`,
- ```bash
- for url in <copied-list>; do curl -k -O $url; done
- ```
- I get a lot of `404 Not Found`. I realized that clicking on the titles will load a player on the page "pre-loading" the audio file, and then I can use `curl`.<sup><b>1</b></sup> It is quite a chore to go through hundreds of files though, so I figured I would make it a bit easier by collecting the "title" elements, and click them one by one until it errors out,
- <sup>\[1] TODO: Why so? It bothers me that I don't understand this part.</sup>
- ```javascript
- const t = Array.from(document.querySelectorAll('td.colTitle'));
- t.pop().click()
- ...
- t.pop().click()
- ```
- but this is still not the best.
- ### The solution thus far
- I cobbled together the snippet below that uses [`MutationObserver`][2] recursively, based on the SO threads below, but I assume that there is a simpler solution (and one that doesn't potentially run out of memory on a page with thousands of episodes).
- + `stackoverflow` [javascript - How to wait until an element exists?](https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists)
- + `stackoverflow` [javascript - How to check if an element has been loaded on a page before running a script?](https://stackoverflow.com/questions/34863788/how-to-check-if-an-element-has-been-loaded-on-a-page-before-running-a-script)
- It seems to get to job done, but the `Promise` will always remain `pending` and it feels very hacky:
- ```javascript
- function waitForElement(querySelector, elemArr) {
- return new Promise((resolve, reject) => {
- if (elemArr.length) {
- console.log(elemArr);
- elemArr.pop().click();
- } else {
- return resolve();
- }
- if (document.querySelectorAll(querySelector).length) {
- waitForElement(querySelector, elemArr);
- }
- const observer = new MutationObserver( () => {
- if (document.querySelectorAll(querySelector).length) {
- observer.disconnect();
- waitForElement(querySelector, elemArr);
- }
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true
- });
- });
- }
- t = Array.from(document.querySelectorAll('td.colTitle'))
- waitForElement("audio", t)
- ```
- [1]: https://i.stack.imgur.com/LTAKW.gif
- [2]: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
#3: Post edited
- I would like to download the old-time radio show [I Love a Mystery](https://www.otrr.org/OTRRLibrary/otrrlibrary.html?idp=4919) from the OTRR website. I figured out how to construct the list of right URLs,
- ```javascript
- const urlStub = "https://otrr.org/OTRRLibrary/jukebox/";
- copy(Array.from(
- document.getElementsByTagName('a')).
- map( a => `"${urlStub}${a.href.split('/').pop()}"` ).
- join(' ')
- )
- ```
- but when I call it with `curl`,
- ```bash
for url in <copied-list>; do curl -k -O $u; done- ```
- I get a lot of `404 Not Found`. I realized that clicking on the titles will load a player on the page "pre-loading" the audio file, and then I can use `curl`. It is quite a chore to go through hundreds of files though, so I figured I would make it a bit easier by collecting the "title" elements, and click them one by one until it errors out,
- ```javascript
- const t = Array.from(document.querySelectorAll('td.colTitle'));
- t.pop().click()
- ...
- t.pop().click()
- ```
- but this is still not the best.
- ### The solution thus far
- I cobbled together the snippet below that uses [`MutationObserver`][2] recursively, based on the SO threads below, but I assume that there is a simpler solution (and one that doesn't potentially run out of memory on a page with thousands of episodes).
- + `stackoverflow` [javascript - How to wait until an element exists?](https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists)
- + `stackoverflow` [javascript - How to check if an element has been loaded on a page before running a script?](https://stackoverflow.com/questions/34863788/how-to-check-if-an-element-has-been-loaded-on-a-page-before-running-a-script)
- It seems to get to job done, but the `Promise` will always remain `pending` and it feels very hacky:
- ```javascript
- function waitForElement(querySelector, elemArr) {
- return new Promise((resolve, reject) => {
- if (elemArr.length) {
- console.log(elemArr);
- elemArr.pop().click();
- } else {
- return resolve();
- }
- if (document.querySelectorAll(querySelector).length) {
- waitForElement(querySelector, elemArr);
- }
- const observer = new MutationObserver( () => {
- if (document.querySelectorAll(querySelector).length) {
- observer.disconnect();
- waitForElement(querySelector, elemArr);
- }
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true
- });
- });
- }
- t = Array.from(document.querySelectorAll('td.colTitle'))
- waitForElement("audio", t)
- ```
- [1]: https://i.stack.imgur.com/LTAKW.gif
- [2]: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
- I would like to download the old-time radio show [I Love a Mystery](https://www.otrr.org/OTRRLibrary/otrrlibrary.html?idp=4919) from the OTRR website. I figured out how to construct the list of right URLs,
- ```javascript
- const urlStub = "https://otrr.org/OTRRLibrary/jukebox/";
- copy(Array.from(
- document.getElementsByTagName('a')).
- map( a => `"${urlStub}${a.href.split('/').pop()}"` ).
- join(' ')
- )
- ```
- but when I call it with `curl`,
- ```bash
- for url in <copied-list>; do curl -k -O $url; done
- ```
- I get a lot of `404 Not Found`. I realized that clicking on the titles will load a player on the page "pre-loading" the audio file, and then I can use `curl`. It is quite a chore to go through hundreds of files though, so I figured I would make it a bit easier by collecting the "title" elements, and click them one by one until it errors out,
- ```javascript
- const t = Array.from(document.querySelectorAll('td.colTitle'));
- t.pop().click()
- ...
- t.pop().click()
- ```
- but this is still not the best.
- ### The solution thus far
- I cobbled together the snippet below that uses [`MutationObserver`][2] recursively, based on the SO threads below, but I assume that there is a simpler solution (and one that doesn't potentially run out of memory on a page with thousands of episodes).
- + `stackoverflow` [javascript - How to wait until an element exists?](https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists)
- + `stackoverflow` [javascript - How to check if an element has been loaded on a page before running a script?](https://stackoverflow.com/questions/34863788/how-to-check-if-an-element-has-been-loaded-on-a-page-before-running-a-script)
- It seems to get to job done, but the `Promise` will always remain `pending` and it feels very hacky:
- ```javascript
- function waitForElement(querySelector, elemArr) {
- return new Promise((resolve, reject) => {
- if (elemArr.length) {
- console.log(elemArr);
- elemArr.pop().click();
- } else {
- return resolve();
- }
- if (document.querySelectorAll(querySelector).length) {
- waitForElement(querySelector, elemArr);
- }
- const observer = new MutationObserver( () => {
- if (document.querySelectorAll(querySelector).length) {
- observer.disconnect();
- waitForElement(querySelector, elemArr);
- }
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true
- });
- });
- }
- t = Array.from(document.querySelectorAll('td.colTitle'))
- waitForElement("audio", t)
- ```
- [1]: https://i.stack.imgur.com/LTAKW.gif
- [2]: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
#2: Post edited
- I would like to download the old-time radio show [I Love a Mystery](https://www.otrr.org/OTRRLibrary/otrrlibrary.html?idp=4919) from the OTRR website. I figured out how to construct the list of right URLs,
- ```javascript
- const urlStub = "https://otrr.org/OTRRLibrary/jukebox/";
- copy(Array.from(
- document.getElementsByTagName('a')).
- map( a => `"${urlStub}${a.href.split('/').pop()}"` ).
- join(' ')
- )
- ```
- but when I call it with `curl`,
- ```bash
- for url in <copied-list>; do curl -k -O $u; done
- ```
- I get a lot of `404 Not Found`. I realized that clicking on the titles will load a player on the page "pre-loading" the audio file, and then I can use `curl`. It is quite a chore to go through hundreds of files though, so I figured I would make it a bit easier by collecting the "title" elements, and click them one by one until it errors out,
- ```javascript
- const t = Array.from(document.querySelectorAll('td.colTitle'));
- t.pop().click()
- ...
- t.pop().click()
- ```
- but this is still not the best.
- ### The solution thus far
I cobbled together the snippet below that uses [`MutationObserver`][2] recursively, based on the SO threads below, but not sure if there would something simpler (and one that doesn't potentially run out of memory a page with thousands of episodes).- + `stackoverflow` [javascript - How to wait until an element exists?](https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists)
- + `stackoverflow` [javascript - How to check if an element has been loaded on a page before running a script?](https://stackoverflow.com/questions/34863788/how-to-check-if-an-element-has-been-loaded-on-a-page-before-running-a-script)
- It seems to get to job done, but the `Promise` will always remain `pending` and it feels very hacky:
- ```javascript
- function waitForElement(querySelector, elemArr) {
- return new Promise((resolve, reject) => {
- if (elemArr.length) {
- console.log(elemArr);
- elemArr.pop().click();
- } else {
- return resolve();
- }
- if (document.querySelectorAll(querySelector).length) {
- waitForElement(querySelector, elemArr);
- }
- const observer = new MutationObserver( () => {
- if (document.querySelectorAll(querySelector).length) {
- observer.disconnect();
- waitForElement(querySelector, elemArr);
- }
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true
- });
- });
- }
- t = Array.from(document.querySelectorAll('td.colTitle'))
- waitForElement("audio", t)
- ```
- [1]: https://i.stack.imgur.com/LTAKW.gif
- [2]: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
- I would like to download the old-time radio show [I Love a Mystery](https://www.otrr.org/OTRRLibrary/otrrlibrary.html?idp=4919) from the OTRR website. I figured out how to construct the list of right URLs,
- ```javascript
- const urlStub = "https://otrr.org/OTRRLibrary/jukebox/";
- copy(Array.from(
- document.getElementsByTagName('a')).
- map( a => `"${urlStub}${a.href.split('/').pop()}"` ).
- join(' ')
- )
- ```
- but when I call it with `curl`,
- ```bash
- for url in <copied-list>; do curl -k -O $u; done
- ```
- I get a lot of `404 Not Found`. I realized that clicking on the titles will load a player on the page "pre-loading" the audio file, and then I can use `curl`. It is quite a chore to go through hundreds of files though, so I figured I would make it a bit easier by collecting the "title" elements, and click them one by one until it errors out,
- ```javascript
- const t = Array.from(document.querySelectorAll('td.colTitle'));
- t.pop().click()
- ...
- t.pop().click()
- ```
- but this is still not the best.
- ### The solution thus far
- I cobbled together the snippet below that uses [`MutationObserver`][2] recursively, based on the SO threads below, but I assume that there is a simpler solution (and one that doesn't potentially run out of memory on a page with thousands of episodes).
- + `stackoverflow` [javascript - How to wait until an element exists?](https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists)
- + `stackoverflow` [javascript - How to check if an element has been loaded on a page before running a script?](https://stackoverflow.com/questions/34863788/how-to-check-if-an-element-has-been-loaded-on-a-page-before-running-a-script)
- It seems to get to job done, but the `Promise` will always remain `pending` and it feels very hacky:
- ```javascript
- function waitForElement(querySelector, elemArr) {
- return new Promise((resolve, reject) => {
- if (elemArr.length) {
- console.log(elemArr);
- elemArr.pop().click();
- } else {
- return resolve();
- }
- if (document.querySelectorAll(querySelector).length) {
- waitForElement(querySelector, elemArr);
- }
- const observer = new MutationObserver( () => {
- if (document.querySelectorAll(querySelector).length) {
- observer.disconnect();
- waitForElement(querySelector, elemArr);
- }
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true
- });
- });
- }
- t = Array.from(document.querySelectorAll('td.colTitle'))
- waitForElement("audio", t)
- ```
- [1]: https://i.stack.imgur.com/LTAKW.gif
- [2]: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
#1: Initial revision
How to programmatically click through a list of elements if one has to wait for a click to load a set of predefined new elements?
I would like to download the old-time radio show [I Love a Mystery](https://www.otrr.org/OTRRLibrary/otrrlibrary.html?idp=4919) from the OTRR website. I figured out how to construct the list of right URLs, ```javascript const urlStub = "https://otrr.org/OTRRLibrary/jukebox/"; copy(Array.from( document.getElementsByTagName('a')). map( a => `"${urlStub}${a.href.split('/').pop()}"` ). join(' ') ) ``` but when I call it with `curl`, ```bash for url in <copied-list>; do curl -k -O $u; done ``` I get a lot of `404 Not Found`. I realized that clicking on the titles will load a player on the page "pre-loading" the audio file, and then I can use `curl`. It is quite a chore to go through hundreds of files though, so I figured I would make it a bit easier by collecting the "title" elements, and click them one by one until it errors out, ```javascript const t = Array.from(document.querySelectorAll('td.colTitle')); t.pop().click() ... t.pop().click() ``` but this is still not the best. ### The solution thus far I cobbled together the snippet below that uses [`MutationObserver`][2] recursively, based on the SO threads below, but not sure if there would something simpler (and one that doesn't potentially run out of memory a page with thousands of episodes). + `stackoverflow` [javascript - How to wait until an element exists?](https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists) + `stackoverflow` [javascript - How to check if an element has been loaded on a page before running a script?](https://stackoverflow.com/questions/34863788/how-to-check-if-an-element-has-been-loaded-on-a-page-before-running-a-script) It seems to get to job done, but the `Promise` will always remain `pending` and it feels very hacky: ```javascript function waitForElement(querySelector, elemArr) { return new Promise((resolve, reject) => { if (elemArr.length) { console.log(elemArr); elemArr.pop().click(); } else { return resolve(); } if (document.querySelectorAll(querySelector).length) { waitForElement(querySelector, elemArr); } const observer = new MutationObserver( () => { if (document.querySelectorAll(querySelector).length) { observer.disconnect(); waitForElement(querySelector, elemArr); } }); observer.observe(document.body, { childList: true, subtree: true }); }); } t = Array.from(document.querySelectorAll('td.colTitle')) waitForElement("audio", t) ``` [1]: https://i.stack.imgur.com/LTAKW.gif [2]: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver