是什么阻止我的代码发现父母的孩子?

时间:2018-12-30 01:04:35

标签: javascript jquery greasemonkey tampermonkey

编写一个Greasemonkey脚本:

  1. 首先收集与条件匹配的元素。这些是<a>标签。
  2. 在简单的for循环中,它将自动单击每个链接。
  3. 然后它将单击另一个<a>链接。
  4. 之后,它将输入一些文本,然后再提交文本以进行服务器处理。
  5. for循环重复该序列,直到列表用尽。

我已经弄清楚了如何构建所需元素的集合,但是由于某种原因,该代码无法访问某些子节点,并返回诸如nullundefined之类的结果。

此部分代码中出现问题:

$(".indeed-apply-button").html();

此类是<a>标记的一部分。

因此,我尝试使用querySelector()访问子节点,该子节点返回未定义。

我尝试使用$();选择器。它将返回[object Object]。附加.html()后,它将返回未定义。

我希望从文档中提取的<a>标签被限制在几个父<div>标签中。
这些<div>标记系列中的代码中的某个地方存在我的代码拒绝或无法访问子节点的地方。

该脚本在求职后在果然网站上运行。它将选择列表中的每个作业,然后单击“应用”按钮。
例如,www.indeed.com/q-programmer-l-maine-jobs.html

什么会导致某些元素无法检索,这是一个更普遍的问题。

$(document).ready(function(){

var jobList = document.querySelectorAll("a[data-tn-element='jobTitle']");

  function clickThenApply (jobNumber) {
    var jobTitle = $(jobList[jobNumber]).attr("title"); //job name
    var jobLink = $(jobList[jobNumber]).attr("href"); //job link
    jobList[jobNumber].click();
    var apply = $(".indeed-apply-button").html();
    console.log("Job title: " + jobTitle);
    console.log("Job link: " + jobLink);
    console.log("success? " + apply);
    return true;
    }

  for (var i = 0; i < jobList.length; i++) {
  var tog = clickThenApply(i);
  }

});

此部分代码中出现问题:

$(".indeed-apply-button").html();

此类是<a>标记的一部分:

<a class="indeed-apply-button" href="javascript:void(0);" id="indeed-ia-...">
  <span class="indeed-apply-button-inner" id="indeed-ia-...">
    <span class="indeed-apply-button-label" id="indeed-ia-...">Apply Now</span>
    <span class="indeed-apply-button-cm">
      <img src="....cloudfront.net/indeedapply/s/14096d1/check.png">
    </span>
  </span>
</a>

我尝试过:

document.querySelector("a.indeed-apply-button");

它返回null / undefined。

如果您能对此提供任何见解,我将不胜感激!

1 个答案:

答案 0 :(得分:0)

正如布罗克(Brock)在评论中指出的那样,问题在于仅单击按钮并不意味着每个元素都已经存在。许多事情可以异步发生来触发。

让我们发挥创意。在我所见过的任何应用程序上,都有您想要的按钮或.view-apply-button。我们将以此为信号表示已发生某些事情。

首先,我们将从现在开始兑现承诺。如果不是内置库,请获取。

function clickThenApply(jobNumber) {
  var jobTitle = $(jobList[jobNumber]).attr("title"); //job name
  var jobLink = $(jobList[jobNumber]).attr("href"); //job link

  return new Promise(function(resolve, reject) {
    // Do the click
    jobList[jobNumber].click();

    // Set our interval. This will test whether there is either of the buttons
    var interval = setInterval(function() {
      var applyButton = $(".indeed-apply-button");
      if (applyButton.length > 0) {
        clearInterval(interval);
        clearTimeout(timeout);
        return resolve({
          name: jobTitle,
          link: jobLink,
          apply: applyButton
        });
      var toSiteButton = $(".view-apply-button");
      if (toSiteButton.length > 0) {
        clearInterval(interval);
        clearTimeout(timeout);
        return resolve({
          name: jobTitle,
          link: jobLink,
          visit: applyButton
        });
    }, 100);
    var timeout = setTimeout(function() {
      if (interval) clearInterval(interval);
      reject({
        name: jobTitle,
        link: jobLink,
        error: "Button not found after 5000ms"
      });
    }, 5000);
  });
}

该代码刻意冗长,因此可读性强,意图明确。每隔100毫秒,我要检查是否存在两个按钮。如果他们这样做,我将用数据解析Promise(然后可以在其他地方处理)。如果5秒后我仍然没有任何东西,我将返回错误。

但是,我留了一些事情要做,

  • 您需要将这些呼叫链接起来才能使其正常工作,因为同时单击多个按钮将在地球上发生麻烦
  • 您还需要确保按钮在使用时不会消失