【问题标题】:How to Query if A URL is Indexed by Google?如何查询一个 URL 是否被 Google 索引?
【发布时间】:2023-03-12 21:55:01
【问题描述】:

我想创建一个 Google 脚本来检查给定的 URL 是否被 Google 索引,所以我编写了以下函数:

function CheckURLForGoogleIndex(url, activesheet) {// Delete the https:// and http:// prefix
  var cururl = url.replace("https://", "");      
  cururl = cururl.replace("http://", "");
  var googlesearchurl = "https://www.google.com/search?q=site:" + encodeURIComponent(cururl);
    var page = UrlFetchApp.fetch(googlesearchurl, {muteHttpExceptions: true}).getContentText();
    // Wait for 1 second before starting another fetch
    Utilities.sleep(1000);
    var number = page.match("did not match any documents");
    if (number) {
      activesheet.getSheetByName("Not Google Index").appendRow([url]);
    } else {
      activesheet.getSheetByName("Google Index").appendRow([url]);
    }  
} 

但是,在调试代码的时候,在调用UrlFetchApp.fetch之后,我只能看到变量page的header。

我尝试使用 Google 索引 URL 而不是索引 URL 来测试该函数,但两者都会在 page.match 函数中返回 null,因此两者都放在“Google 索引”表中。

我的函数有什么问题?

谢谢

注意:

我在https://groups.google.com/g/google-apps-script-community/c/gs1qUuKwgn4上问过这个问题,但没有人回答,所以我必须在这里问。

示例输入和输出

输入1:

网址 = https://www.datanumen.com/

activesheet = 包含工作表“Google Index”和“Not Google Index”的 GoogleSheet

预期输出 1:由于 https://www.datanumen.com/ 已被 Google 索引,它将被添加到“Google 索引”表中。

page = "<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>site:www.datanumen.com/ - Google Search…"

输入2:

网址 = https://www.datanumen.com/notindexedurl/

activesheet = 包含工作表“Google Index”和“Not Google Index”的 GoogleSheet

预期输出 2:由于 https://www.datanumen.com/notindexedurl/ 未被 Google 索引,它将被添加到“NOT Google Index”表中。

page = "<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>site:www.datanumen.com/notindexurl/ - G…"

问题目前是 Input1 和 Input2 的问题,实际结果是:URL 将始终添加到“Google 索引”表,因为搜索结果根本不会包含“不匹配任何文档”文本。

更新

我添加了 console.log(page);并再次调试。对于 Input1,我得到以下结果:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="initial-scale=1"><title>https://www.google.com/search?q=site:www.datanumen.com%2F</title></head>
<body style="font-family: arial, sans-serif; background-color: #fff; color: #000; padding:20px; font-size:18px;" onload="e=document.getElementById('captcha');if(e){e.focus();}">
<div style="max-width:400px;">
<hr noshade size="1" style="color:#ccc; background-color:#ccc;"><br>
<form id="captcha-form" action="index" method="post">
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>var submitCallback = function(response) {document.getElementById('captcha-form').submit();};</script>
<div id="recaptcha" class="g-recaptcha" data-sitekey="6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b" data-callback="submitCallback" data-s="c5Hy4maqTFv3SzYRiWhpsqYF2isZmauUQnLVljOiED_PiaVWJWCsHMzRAZyh8HLCBHJ_mjET7yODJu8AlZ33_xGAQ8TcKuXAd7rQpsYakaGKPD8USiGSFhiII2ai-Cf_B26i1Ufpko-qYQ8V3rezhiSXxi5J2yHZ-_WwEj8ukzy5znxzVurTM_2cY243Q4ofwP7E7eWBaHIg6N3ofmPuFXd-uRIUU4z0cU_pas8"></div>
<input type='hidden' name='q' value='EgRrsuB5GKmx6oUGIhBKAdWty9nssg-nAtyy9n7hMgFy'><input type="hidden" name="continue" value="https://www.google.com/search?q=site:www.datanumen.com%2F">
</form>
<hr noshade size="1" style="color:#ccc; background-color:#ccc;">

<div style="font-size:13px;">
<b>About this page</b><br><br>

Our systems have detected unusual traffic from your computer network.  This page checks to see if it&#39;s really you sending the requests, and not a robot.  <a href="#" onclick="document.getElementById('infoDiv').style.display='block';">Why did this happen?</a><br><br>

<div id="infoDiv" style="display:none; background-color:#eee; padding:10px; margin:0 0 15px 0; line-height:1.4em;">
This page appears when Google automatically detects requests coming from your computer network which appear to be in violation of the <a href="//www.google.com/policies/terms/">Terms of Service</a>. The block will expire shortly after those requests stop.  In the meantime, solving the above CAPTCHA will let you continue to use our services.<br><br>This traffic may have been sent by malicious software, a browser plug-in, or a script that sends automated requests.  If you share your network connection, ask your administrator for help &mdash; a different computer using the same IP address may be responsible.  <a href="//support.google.com/websearch/answer/86640">Learn more</a><br><br>Sometimes you may be asked to solve the CAPTCHA if you are using advanced terms that robots are known to use, or sending requests very quickly.
</div>

IP address: 107.178.224.121<br>Time: 2021-06-04T21:18:34Z<br>URL: https://www.google.com/search?q=site:www.datanumen.com%2F<br>
</div>
</div>
</body>
</html>

【问题讨论】:

  • 为了正确理解您的问题,您能否提供您期望的示例输入和输出值?通过这个,我想试着理解你的问题。
  • 看起来你不能这样做。当我尝试时,我得到了不寻常的流量页面:support.google.com/websearch/answer/86640
  • 你能分享你从page = UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getContentText() 得到的输出吗(另外,这里的url 不应该是googlesearchurl)吗?
  • @Tanaike,我已更新问题以包含两个示例输入和输出。
  • @RafaGuillermo,谢谢。我已将 url 替换为 googlesearchurl。但即使在此之后,如果我调试代码,那么对于 Input2,URL 将正确添加到“非 Google 索引”表中。但是,如果运行代码,那么所有 URL 都将添加到“Google 索引”表中,即使是输入 2。可能问题是由您评论中提到的异常流量页面引起的。但我看不到。

标签: google-apps-script


【解决方案1】:

答案:

不幸的是,直接尝试使用 UrlFetchApp 抓取搜索结果的网络将无法正常工作。不过,您可以使用第三方工具来获取搜索结果的数量。

更多信息:

我使用指数退避方法对此进行了测试,当UrlFetchApp 调用获取请求时,该方法有时能够克服429 错误。

当使用UrlFetchApp 进行网页抓取或连接到 API 时,服务器可能会以too many requests - 或HTTP Error 429 为由拒绝请求。

Google Apps 脚本在云端运行,来自 Google 拥有的池中的一组 IP 地址。您实际上可以看到所有 IP 范围here。大多数网站(尤其是谷歌等大公司)都有适当的架构来防止使用机器人抓取他们的网站并减慢流量。

有时可以通过混合使用指数退避和随机时间间隔as shown for the Binance API完全披露:此 GitHub 存储库由我编写。)来克服此错误。

我认为要么是 Google 直接阻止了 Apps 脚本 IP 池,要么就是有太多人在尝试相同的事情 - 因为使用相同的技术我无法获得任何不涉及输入验证码的响应,因为我们在上面的 cmets 中讨论过,可以在 page 字符串的日志中看到。

可以做什么:

您可以使用许多第三方 API 来执行此操作,我建议您搜索一个满足您需求的 API。

我测试了一个名为Authoritas 的工具,它返回不同关键字的搜索引擎索引。 API 是异步的,因此可能需要一分钟才能获得响应,因此需要制定 Web 应用解决方案。

我使用的流程如下:

function makeApiCall(url, method, site) {
  const public_key = ""
  const private_key = ""
  const salt = "" 
  let timestamp = Date.now()

  const hash = Utilities.computeHmacSha256Signature(timestamp + public_key + salt, private_key)
  const headers = {
    "Authorization": "KeyAuth publicKey=" + public_key + " hash=" + toHexString(hash) + " ts=" + timestamp,
    "Content-Type": "application/json"
  }

  const requestParameters = {
    "search_engine": "google",
    "region": "us",
    "language": "en",
    "max_results": 100,
    "phrase": site,
    "search_type": "web",
    "user_agent": "pc",
    "parameters": {
      "priority": "standard"
    },
    "callback_type": "full",
    "callback": "script-web-app-exec-url"
  }

  const options = {
    "method": method,
    "headers": headers,
    "muteHttpExceptions": true,
    "payload": JSON.stringify(requestParameters)
  }

  const response = UrlFetchApp.fetch(url, options)
  return response
}

function toHexString(byteArray) {
  const hexString = Array.from(byteArray, function(byte) {
    return ('0' + (byte & 0xFF).toString(16)).slice(-2)
  }).join('')
  return hexString
}

还有一个doPost(e) 函数,以便在API 返回数据时对其进行处理:

function doPost(e) {
  const jsonData = JSON.parse(e.postData.contents)
  const pages = jsonData.response.summary.pages
  const ss = SpreadsheetApp.openById("1QBzDdGn1yaUxFJciLH_Ru-BbLHuBIZTUk2UnrUShGw0") 
  
  if (Object.keys(pages).length == 0) {
    ss.getSheetByName("Not Google Index").appendRow([jsonData.request.phrase])
  }
  else {
    ss.getSheetByName("Google Index").appendRow([jsonData.request.phrase])
  }  
}

然后我从这里发布了带有设置的 Web 应用程序:

  • Execute as: me
  • Who has access: Anyone不是Anyone with a Google account

记得在提供时复制 Web 应用 URL 并将其粘贴到负载的 "callback": "script-web-app-exec-url" 部分(通常可以使用 ScriptApp.getService().getUrl(),但根据 this issue,当从脚本编辑器运行代码时,此方法返回 /dev 链接而不是 /exec 链接,这将不起作用)。

然后可以像这样简单地运行:

function run() {
  const req = makeApiCall("v3.api.analyticsseo.com/serps/", "POST", "asdhfdhdfgdsfser.com")
  console.log(req.getContentText())
}

请求将运行,来自 API 的响应将被记录,其中包含请求对象,然后当请求准备好时,Authoritas API 将调用您在 callback 参数中提供的脚本 URL,它将运行 @ 987654351@方法。

这是一个复杂的解决方法,但不幸的是,如今网络抓取变得越来越难。

参考资料:

【讨论】:

  • 请让我知道您是否可以完成这项工作,我会看看是否可以提供帮助!
  • 非常感谢。 API 是免费的还是我必须为其计划付费才能调用它?
  • 每月前 1000 次调用免费,因此根据您的使用情况,您可以使用此工作表(如果您不想付费,也可以为额外的 API 密钥创建第二个帐户) !)
  • @Rafa Guillermo 我试过这个方法。但它在这一行中不断给出错误“无效参数:键”:Utilities.computeHmacSha256Signature(timestamp + public_key + salt, private_key)
猜你喜欢
  • 2011-05-22
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多