【问题标题】:Finding a selector that changes after each page render查找在每个页面呈现后更改的选择器
【发布时间】:2021-01-07 16:18:12
【问题描述】:

注意:这不是我自己的网站!

我有一个按钮,我想点击我的项目。 选择器是:

#pop_1609947672477 > div > div > div.inner-content > div > div > div > button

问题是,#pop 之后的数字在每次刷新时都会发生变化。

也许你能帮我解决这个问题?

【问题讨论】:

  • 这是一种常见的反爬虫技术。我假设您正在尝试抓取不想被抓取的人。无论哪种方式,根据您在此处添加的信息量非常有限,无法回答此答案
  • #pop_1609947672477页面中唯一以#pop_开头的元素吗?
  • 是的,我自己从 div 中复制选择器

标签: javascript node.js puppeteer


【解决方案1】:

如果你感兴趣的元素是页面内唯一一个id以#pop_开头的元素,你可以如下选择:

[id^=pop_] > div > div > div.inner-content > div > div > div > button

如果有多个元素的 id 以#pop_ 开头,那么您将需要找出可以区分它们的模式。

例如,如果要查找的元素始终作为第一个元素出现,则可以在选择器中添加一些额外的约束,或者在选择后过滤结果。

const elements = document.querySelectorAll('[id^=pop_] > div > div > div.inner-content > div > div > div > button');

// highlight the selected elements
elements.forEach(el => el.style.background = 'tomato');
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="pop_1234">
      <div>
        <div>
          <div class="inner-content">
            <div>
              <div>
                <div>
                  <button>The Element</button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div id="not_pop_1234">
      <div>
        <div>
          <div class="inner-content">
            <div>
              <div>
                <div>
                  <button>Not The Element</button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

【讨论】:

    【解决方案2】:

    有一种方法可以找到并单击按钮,请参阅此脚本。我已经删除了所有内部 div,因为它会使水有点混浊。

    神奇的是这个位,基本上'div[id^="pop_"] button' 要求页面返回所有以id=pop_ 开头的元素(^ 就是这样做的)

    所以看看并运行这个脚本。这将打开 chrome,按 F12 并导航到控制台选项卡,3 秒后您将看到一条 console.log 消息,因此我们知道该按钮已被单击。

    const puppeteer = require('puppeteer');
    
    const html = `
    <html>
        <body>
        <div id="pop_1111">
          <button onclick="report(1111);">The first element</button>
        </div>
        <div id="pop_2222">
          <button onclick="report(2222);">The second element</button>
        </div>
        <div id="pop_9876">
          <button onclick="report(9876);">The third element</button>
        </div>
        <script>
          function report(val) {
            console.log(val);
          };
        </script>
      </body>
    </html>`;
    
    (async () => {
      const browser = await puppeteer.launch({ headless : false});
      const page = await browser.newPage();
      await page.goto(`data:text/html,${html}`);
    
      await page.waitForTimeout(3000);
      //This will click the first button it finds
      await page.$eval('div[id^="pop_"] button', btn => btn.click());
      await page.waitForTimeout(10000);
    
      await browser.close();
    })();
    

    如果您想点击所有按钮,那么您的代码将如下所示

      await page.waitForTimeout(3000);
      var data = await page.$$('div[id^="pop_"] button', e => e.map((btn) => btn));
      await data[0].click();
      await data[1].click();
      await data[2].click();
      await page.waitForTimeout(10000);
    

    这会产生以下结果

    【讨论】:

      【解决方案3】:

      您可以在此按钮上放置data-testid,并使用data-testid 选择器代替长选择器。

      Example

      【讨论】:

      • 这不是我的网站
      • 就好像他们不想被爬一样不是吗
      • 您可以尝试选择按钮的父元素不变,然后选择按钮?
      • 对不起,我没有找到你
      猜你喜欢
      • 2015-06-27
      • 1970-01-01
      • 2019-07-04
      • 1970-01-01
      • 2011-01-06
      • 2019-12-17
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      相关资源
      最近更新 更多