Puppeteer $ .eval选择嵌套元素

问题描述 投票:0回答:2

让我们说我给这样的情况

<div id="details-container" class="style-scope ytd-channel-about-metadata-renderer">
         <yt-formatted-string class="subheadline style-scope ytd-channel-about-metadata-renderer">Details</yt-formatted-string>
        <table class="style-scope ytd-channel-about-metadata-renderer">
          <tbody class="style-scope ytd-channel-about-metadata-renderer"><tr class="style-scope ytd-channel-about-metadata-renderer">
            <td class="label style-scope ytd-channel-about-metadata-renderer">
              <yt-formatted-string class="style-scope ytd-channel-about-metadata-renderer"></yt-formatted-string>
            </td>
            <td class="style-scope ytd-channel-about-metadata-renderer">
              <ytd-button-renderer align-by-text="" class="style-scope ytd-channel-about-metadata-renderer" button-renderer=""></ytd-button-renderer>
              <div id="captcha-container" class="style-scope ytd-channel-about-metadata-renderer"></div>
              <div id="email-container" class="style-scope ytd-channel-about-metadata-renderer"></div>
              <a id="email" target="_blank" class="style-scope ytd-channel-about-metadata-renderer" href="mailto:undefined" hidden=""></a>
            </td>
          </tr>
          <tr class="style-scope ytd-channel-about-metadata-renderer">
            <td class="label style-scope ytd-channel-about-metadata-renderer">
              <yt-formatted-string class="style-scope ytd-channel-about-metadata-renderer"><span class="deemphasize style-scope yt-formatted-string"> Location:   </span></yt-formatted-string>
            </td>
            <td class="style-scope ytd-channel-about-metadata-renderer">
              <yt-formatted-string class="style-scope ytd-channel-about-metadata-renderer">YourCountry</yt-formatted-string>
            </td>
          </tr>
        </tbody></table>
      </div>

让我说我需要得到“YourCountry”我如何实际获得这个元素?

到目前为止,我试过:

  const location = await page.$$eval(
    "#details-container > table > tbody:nth-child(1) > tr:nth-child(1) > yt-formatted-string",
    locationEl => locationEl.innerHTML
  );
console.log(location) // Undefined

不确定如何去做,尝试返回tr然后再次评估tr [1]不起作用,因为它说tr没有函数。$$ eval。

请注意,我正在使用apify来获取页面。

javascript css-selectors puppeteer apify
2个回答
1
投票

在你提供的HTML中,你想要的yt-formatted-string元素是第二个td下的第二个tr的直接孩子,但你试图将它与第二个yt-formatted-string的直接孩子的tr相匹配。你需要修复你的选择器。例如:

console.log("HTML:", document.querySelector("#details-container > table > tbody > tr:nth-child(2) > td:nth-child(2) > yt-formatted-string").innerHTML)
<div id="details-container" class="style-scope ytd-channel-about-metadata-renderer">
  <yt-formatted-string class="subheadline style-scope ytd-channel-about-metadata-renderer">Details</yt-formatted-string>
  <table class="style-scope ytd-channel-about-metadata-renderer">
    <tbody class="style-scope ytd-channel-about-metadata-renderer">
      <tr class="style-scope ytd-channel-about-metadata-renderer">
        <td class="label style-scope ytd-channel-about-metadata-renderer">
          <yt-formatted-string class="style-scope ytd-channel-about-metadata-renderer"></yt-formatted-string>
        </td>
        <td class="style-scope ytd-channel-about-metadata-renderer">
          <ytd-button-renderer align-by-text="" class="style-scope ytd-channel-about-metadata-renderer" button-renderer=""></ytd-button-renderer>
          <div id="captcha-container" class="style-scope ytd-channel-about-metadata-renderer"></div>
          <div id="email-container" class="style-scope ytd-channel-about-metadata-renderer"></div>
          <a id="email" target="_blank" class="style-scope ytd-channel-about-metadata-renderer" href="mailto:undefined" hidden=""></a>
        </td>
      </tr>
      <tr class="style-scope ytd-channel-about-metadata-renderer">
        <td class="label style-scope ytd-channel-about-metadata-renderer">
          <yt-formatted-string class="style-scope ytd-channel-about-metadata-renderer"><span class="deemphasize style-scope yt-formatted-string"> Location:   </span></yt-formatted-string>
        </td>
        <td class="style-scope ytd-channel-about-metadata-renderer">
          <yt-formatted-string class="style-scope ytd-channel-about-metadata-renderer">YourCountry</yt-formatted-string>
        </td>
      </tr>
    </tbody>
  </table>
</div>

you should be able to call $$eval &c. if you have an ElementHandle。问题是你的选择器不匹配,所以你没有。


2
投票

我更喜欢使用jQuery。这是查询元素的最佳方法。你可以从Apify utils中注入jQuery。

const { puppeteer } = Apify.utils;

await puppeteer.injectJQuery(page);
const location = await page. evaluate(() => {
  return $('#details-container yt-formatted-string').last().text();
});
console.log(location);
© www.soinside.com 2019 - 2024. All rights reserved.