PuppeteerJS - как я могу очистить текстовое содержимое от элемента td, основанного на тексте смежного td? - PullRequest
1 голос
/ 03 апреля 2019

Я пытаюсь очистить ссылку из ячейки td рядом с другим тд, помечая тип или описание ссылки с помощью кукловода. Нет классов или идентификаторов, отличающих эти ячейки тд, кроме текстового содержимого

         <tr>
            <td scope="row">1</td>
            <td scope="row">10-Q</td>
            <td scope="row"><a href="/Archives/edgar/data/1065280/000106528018000538/nflx-093018x10qxdoc.htm">nflx-093018x10qxdoc.htm</a></td>
            <td scope="row">10-Q</td>
            <td scope="row">1339833</td>
         </tr>
         <tr class="blueRow">
            <td scope="row">2</td>
            <td scope="row">EXHIBIT 31.1</td>
            <td scope="row"><a href="/Archives/edgar/data/1065280/000106528018000538/nflx311_q32018.htm">nflx311_q32018.htm</a></td>
            <td scope="row">EX-31.1</td>
            <td scope="row">14914</td>
         </tr>
         <tr>
            <td scope="row">3</td>
            <td scope="row">EXHIBIT 31.2</td>
            <td scope="row"><a href="/Archives/edgar/data/1065280/000106528018000538/nflx312_q32018.htm">nflx312_q32018.htm</a></td>
            <td scope="row">EX-31.2</td>
            <td scope="row">14553</td>
         </tr>
         <tr class="blueRow">
            <td scope="row">4</td>
            <td scope="row">EXHIBIT 32.1</td>
            <td scope="row"><a href="/Archives/edgar/data/1065280/000106528018000538/nflx321_q32018.htm">nflx321_q32018.htm</a></td>
            <td scope="row">EX-32.1</td>
            <td scope="row">12406</td>
         </tr>

ссылка после тд, содержащая '10Q'

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Вы можете сделать это с помощью vanila javascript,

// find all tr elements
[...document.querySelectorAll('tr')]

 // check which one of them includes the word
 .find(e=>e.innerText.includes('10-Q'))

 // get the link inside
 .querySelector('a') 

enter image description here

С кукловодом $eval это можно упростить,

page.$$eval('tr', eachTr=> eachTr.find(e=>e.innerText.includes('10-Q')).querySelector('a'))

Или page.evaluate,

page.evaluate(()=> {
 // find all tr elements
    return [...document.querySelectorAll('tr')]

     // check which one of them includes the word
     .find(e=>e.innerText.includes('10-Q'))

     // get the link inside
     .querySelector('a')

     // do whatever you want to do with this
     .href
})

Удобочитаемое решение.

2 голосов
/ 03 апреля 2019

Выражения XPath

Вот где XPath выражение отлично:

//td[contains(., '10-Q')]/following-sibling::td[1]/a[1]

Это выражение XPath запрашивает элемент td, содержащий текст 10-Q .Затем он возьмет следующий элемент td и вернет первую ссылку (a) внутри.В качестве альтернативы, вы можете использовать //td[text()='10-Q']/ в начале, если вы не хотите, чтобы элемент содержал текст, но чтобы он точно соответствовал ему.

Использование внутри кукловода

Чтобы получитьэлемент с кукловодом, используйте функцию page.$x.Чтобы извлечь информацию (например, href) из запрашиваемого узла, используйте page.evaluate.

Собрав все вместе, код выглядит следующим образом:

const [linkHandle] = await page.$x("//td[contains(., '10-Q')]/following-sibling::td[1]/a[1]");
const address = await page.evaluate(link => link.href, linkHandle);
...