PuppeteerJS — как я могу удалить текстовое содержимое из элемента td на основе текста соседнего td?

#element #puppeteer #scrape

#элемент #кукловод #очистить

Вопрос:

Я пытаюсь удалить ссылку из ячейки td, смежной с другим td, помечающим тип или описание ссылки, используя puppeteer. Нет никаких классов или идентификаторов, отличающих эти ячейки 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>

  

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

Комментарии:

1. Можете ли вы добавить HTML образца элемента td, который вы пытаетесь очистить?

Ответ №1:

Выражения XPath

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

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

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

Использование в puppeteer

Чтобы получить элемент с помощью puppeteer, используйте 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);
  

Ответ №2:

Вы можете сделать это с помощью 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') 
  

введите описание изображения здесь

С помощью puppeteer $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
})
  

Читаемое решение.