#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
})
Читаемое решение.