I'd like to extract data from HTML tags to form the following string:
Adrien Petitpas, Julien M.Jaquet, Pascal Sciarini
Where Adrien
, Julien M.
and Pascal
are first names, and the other - last names.
This is how I extract name:
Array.from(document.querySelectorAll('span.text.given-name')).map(s=>s.outerText)
It gives me: ['Adrien', 'Julien M.', 'Pascal']
Extracting surnames is also easy:
Array.from(document.querySelectorAll('span.text.surname')).map(s=>s.outerText)
How to combine my two selects, to get name and surname combined?
I tried with the script below, but I got wrong result: 'Adrien Petitpas'
, which is only the first person in tags.
Note that I'm interested in vanilla JavaScript.
Here's the page I have html text from: https://www.sciencedirect.com/science/article/pii/S0261379420301244?via%3Dihub
const names = Array.from(document.querySelectorAll('#author-group')) .map(e => e.querySelector('span.text.given-name').outerText + ' ' + e.querySelector('span.text.surname').outerText) .join(', '); console.log(names)
<div id="author-group"> <span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> <svg focusable="false" viewBox="0 0 106 128" width="19.875" height="24" class="icon icon-person"> <path d="m11.07 1.2e2l0.84-9.29c1.97-18.79 23.34-22.93 41.09-22.93 17.74 0 39.11 4.13 41.08 22.84l0.84 9.38h10.04l-0.93-10.34c-2.15-20.43-20.14-31.66-51.03-31.66s-48.89 11.22-51.05 31.73l-0.91 10.27h10.03m41.93-102.29c-9.72 0-18.24 8.69-18.24 18.59 0 13.67 7.84 23.98 18.24 23.98s18.24-10.31 18.24-23.98c0-9.9-8.52-18.59-18.24-18.59zm0 52.29c-15.96 0-28-14.48-28-33.67 0-15.36 12.82-28.33 28-28.33s28 12.97 28 28.33c0 19.19-12.04 33.67-28 33.67"></path> </svg> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span><span class="text surname">Sciarini</span> </div>
You can use nextElementSibling
to get the element containing the surname.
console.log(Array.from( document.querySelectorAll('span.text.given-name'), e => e.textContent + ' ' + e.nextElementSibling.textContent ));
<span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> <svg focusable="false" viewBox="0 0 106 128" width="19.875" height="24" class="icon icon-person"> <path d="m11.07 1.2e2l0.84-9.29c1.97-18.79 23.34-22.93 41.09-22.93 17.74 0 39.11 4.13 41.08 22.84l0.84 9.38h10.04l-0.93-10.34c-2.15-20.43-20.14-31.66-51.03-31.66s-48.89 11.22-51.05 31.73l-0.91 10.27h10.03m41.93-102.29c-9.72 0-18.24 8.69-18.24 18.59 0 13.67 7.84 23.98 18.24 23.98s18.24-10.31 18.24-23.98c0-9.9-8.52-18.59-18.24-18.59zm0 52.29c-15.96 0-28-14.48-28-33.67 0-15.36 12.82-28.33 28-28.33s28 12.97 28 28.33c0 19.19-12.04 33.67-28 33.67"></path> </svg> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a>
You can loop over the author anchors that contain the name spans. Then use querySelector
to find the given name and surname inside of the author.
const authors = document.querySelectorAll('.author'); const names = Array.from(authors).map(author => { const givenName = author.querySelector('.given-name'); const surName = author.querySelector('.surname'); return `${givenName.textContent} ${surName.textContent}`; }); console.log(names);
<a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span> <span class="text surname">Jaquet</span> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span> <span class="text surname">Sciarini</span> </span> </a>
I had to complete some of the HTML to get it working, but here's one way to do it.
The problem in your current approach is that your map
function receives an array with a single element. Hence the current output is the way it is.
I just changed your selector from #author-group
to .author
console.log(Array.from(document.querySelectorAll('.author')) .map(e => e.querySelector('span.text.given-name').outerText + ' ' + e.querySelector('span.text.surname').outerText) .join(', '));
<div id="author-group"> <a class="author size-m workspace-trigger" name="bau1" href="#!"> <span class="content"> <span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span><span class="text surname">Sciarini</span> </span> </a> </div>
Another way, if you would like to just combine what you've figured out till now, would be to just concatenate the two arrays:
const givenNames = Array.from(document.querySelectorAll('span.text.given-name')).map(s => s.outerText)
const surnames = Array.from(document.querySelectorAll('span.text.surname')).map(s => s.outerText)
console.log(givenNames.map((givenName, i) => givenName + ' ' + surnames[i]).join(', '));
I think nextSibling
is useful in this context :
let output = []; document.querySelectorAll(".given-name").forEach( el => output.push(el.outerText + " " + el.nextSibling.outerText)); console.log(output);
<span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> <svg focusable="false" viewBox="0 0 106 128" width="19.875" height="24" class="icon icon-person"> <path d="m11.07 1.2e2l0.84-9.29c1.97-18.79 23.34-22.93 41.09-22.93 17.74 0 39.11 4.13 41.08 22.84l0.84 9.38h10.04l-0.93-10.34c-2.15-20.43-20.14-31.66-51.03-31.66s-48.89 11.22-51.05 31.73l-0.91 10.27h10.03m41.93-102.29c-9.72 0-18.24 8.69-18.24 18.59 0 13.67 7.84 23.98 18.24 23.98s18.24-10.31 18.24-23.98c0-9.9-8.52-18.59-18.24-18.59zm0 52.29c-15.96 0-28-14.48-28-33.67 0-15.36 12.82-28.33 28-28.33s28 12.97 28 28.33c0 19.19-12.04 33.67-28 33.67"></path> </svg> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span><span class="text surname">Sciarini</span>
I would use a good selector and a forEach
const names = [] document.querySelectorAll('#author-group span.text') .forEach((span,i) => { if (span.classList.contains("given-name")) names.push(span.textContent); else names[names.length-1] += ` ${span.textContent}` }) console.log(names)
<div id="author-group"> <span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> <svg focusable="false" viewBox="0 0 106 128" width="19.875" height="24" class="icon icon-person"> <path d="m11.07 1.2e2l0.84-9.29c1.97-18.79 23.34-22.93 41.09-22.93 17.74 0 39.11 4.13 41.08 22.84l0.84 9.38h10.04l-0.93-10.34c-2.15-20.43-20.14-31.66-51.03-31.66s-48.89 11.22-51.05 31.73l-0.91 10.27h10.03m41.93-102.29c-9.72 0-18.24 8.69-18.24 18.59 0 13.67 7.84 23.98 18.24 23.98s18.24-10.31 18.24-23.98c0-9.9-8.52-18.59-18.24-18.59zm0 52.29c-15.96 0-28-14.48-28-33.67 0-15.36 12.82-28.33 28-28.33s28 12.97 28 28.33c0 19.19-12.04 33.67-28 33.67"></path> </svg> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span><span class="text surname">Sciarini</span></div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.