{"id":15558,"date":"2026-09-05T14:11:00","date_gmt":"2026-09-05T12:11:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/"},"modified":"2026-09-05T15:08:37","modified_gmt":"2026-09-05T13:08:37","slug":"crawler-ip-verifier-googlebot-bingbot-gptbot","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/","title":{"rendered":"Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 20px;\">A User-Agent string is free text; anything can call itself Googlebot. What cannot be forged is the address it comes from. Operators publish two kinds of proof: a reverse DNS name under their own domain that resolves back to the same address, and JSON lists of the address ranges their crawlers use. This check does both from this server, refreshes the lists once a day, and asks RDAP who owns the network, so a scraper on a rented cloud machine stands out from the real thing.<\/p>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; margin-bottom: 14px;\">\n<div>\n            <label for=\"ci-ip\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">IP address from the log (IPv4 or IPv6)<\/label><br \/>\n            <input id=\"ci-ip\" type=\"text\" value=\"66.249.66.1\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; box-sizing: border-box; font-family: monospace;\">\n        <\/div>\n<div>\n            <label for=\"ci-behauptet\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Claims to be<\/label><br \/>\n            <select id=\"ci-behauptet\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; box-sizing: border-box;\"><option value=\"keine\">Unknown, just identify it<\/option><option value=\"googlebot\" selected>Googlebot<\/option><option value=\"google-special\">AdsBot \/ Mediapartners (Google)<\/option><option value=\"google-user\">Google user-triggered fetcher<\/option><option value=\"bingbot\">Bingbot<\/option><option value=\"gptbot\">GPTBot (OpenAI)<\/option><option value=\"oai-searchbot\">OAI-SearchBot (OpenAI)<\/option><option value=\"chatgpt-user\">ChatGPT-User (OpenAI)<\/option><option value=\"applebot\">Applebot<\/option><option value=\"perplexitybot\">PerplexityBot<\/option><option value=\"perplexity-user\">Perplexity-User<\/option><option value=\"ahrefsbot\">AhrefsBot<\/option><option value=\"yandex\">YandexBot<\/option><option value=\"baidu\">Baiduspider<\/option><option value=\"duckduckbot\">DuckDuckBot<\/option><option value=\"facebook\">facebookexternalhit \/ Meta<\/option><option value=\"claudebot\">ClaudeBot (Anthropic)<\/option><option value=\"ccbot\">CCBot (Common Crawl)<\/option><option value=\"bytespider\">Bytespider (ByteDance)<\/option><\/select>\n        <\/div>\n<\/p><\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.82rem; margin-bottom: 16px;\">From this server: a reverse DNS lookup, a forward lookup of the resulting name, one RDAP query for the address, and, at most once a day, the public range lists of the crawler operators. The address entered is not contacted. The query is protected by reCAPTCHA v3; the calling IP address and the address checked are stored for one hour to limit the rate.<\/p>\n<p>    <button id=\"ci-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: var(--on-accent, #0b1114); border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Verify the address<\/button><\/p>\n<div id=\"ci-ausgabe\" style=\"margin-top: 22px;\"><\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.8rem; margin: 24px 0 0;\">Limits worth knowing: not every operator publishes anything (ClaudeBot, CCBot, Bytespider have neither lists nor reverse DNS conventions, so their claims are unverifiable rather than false); the lists are refreshed daily and an address added today may be missing until tomorrow; the data centre hint comes from the network name and is a heuristic; and a confirmed crawler address says nothing about whether the request itself was welcome.<\/p>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"A User-Agent string is free text; anything can call itself Googlebot. What cannot be forged is the address it comes from. Operators publish two kinds of proof: a reverse DNS name under their own domain that resolves back to the same address, and JSON lists of the address ranges their crawlers use. This check does both from this server, refreshes the lists once a day, and asks RDAP who owns the network, so a scraper on a rented cloud machine stands out from the real thing.\",\"label_ip\":\"IP address from the log (IPv4 or IPv6)\",\"label_behauptet\":\"Claims to be\",\"behauptet_keine\":\"Unknown, just identify it\",\"datenschutz\":\"From this server: a reverse DNS lookup, a forward lookup of the resulting name, one RDAP query for the address, and, at most once a day, the public range lists of the crawler operators. The address entered is not contacted. The query is protected by reCAPTCHA v3; the calling IP address and the address checked are stored for one hour to limit the rate.\",\"knopf\":\"Verify the address\",\"laeuft\":\"Looking up DNS, lists and RDAP...\",\"grenze\":\"Limits worth knowing: not every operator publishes anything (ClaudeBot, CCBot, Bytespider have neither lists nor reverse DNS conventions, so their claims are unverifiable rather than false); the lists are refreshed daily and an address added today may be missing until tomorrow; the data centre hint comes from the network name and is a heuristic; and a confirmed crawler address says nothing about whether the request itself was welcome.\",\"ergebnis_echt\":\"{name} confirmed for {ip}\",\"ergebnis_echt_erklaerung\":\"The address is proven to belong to the operator, by a forward-confirmed reverse DNS name, by a published range, or both.\",\"ergebnis_gefaelscht\":\"Not {name}: {ip} is not one of its addresses\",\"ergebnis_gefaelscht_erklaerung\":\"The operator publishes how to recognise its crawler, and this address meets none of it. A request from here with that User-Agent is a forgery.\",\"ergebnis_unpruefbar\":\"{name} cannot be verified from {ip}\",\"ergebnis_unpruefbar_erklaerung\":\"This operator publishes neither address ranges nor a reverse DNS convention. The claim is neither confirmed nor refuted.\",\"ergebnis_erkannt\":\"{ip} belongs to {erkannt}\",\"ergebnis_erkannt_erklaerung\":\"Without a claim to check, the address was matched against every known operator, and one of them fits.\",\"ergebnis_unbekannt\":\"{ip} matches no known crawler\",\"ergebnis_unbekannt_erklaerung\":\"No published range and no operator reverse DNS name. The network owner below is the best remaining clue.\",\"h_belege\":\"Evidence\",\"zeile_ip\":\"Address\",\"zeile_behauptet\":\"Claim\",\"zeile_ptr\":\"Reverse DNS (PTR)\",\"zeile_vorwaerts\":\"Forward confirmation\",\"zeile_rdns\":\"Operator domain\",\"zeile_listen\":\"Published ranges\",\"zeile_netz\":\"Network (RDAP)\",\"zeile_bereich\":\"Allocation\",\"zeile_rechenzentrum\":\"Hosting \\\/ cloud\",\"zeile_dauer\":\"Took\",\"zeile_limit\":\"Checks left this hour\",\"vorwaerts_ok\":\"the name resolves back to this address\",\"vorwaerts_fehlt\":\"the name resolves to {ips}, not to this address\",\"rdns_kurz\":\"{name} ({domain})\",\"wert_keiner\":\"none\",\"h_listen\":\"Published range lists\",\"listen_stand\":\"as of {datum}\",\"spalte_liste\":\"List\",\"spalte_betreiber\":\"Operator\",\"spalte_praefixe\":\"Prefixes\",\"spalte_treffer\":\"Match\",\"liste_nicht_geladen\":\"not loaded\",\"h_befunde\":\"Findings\",\"stufe_hoch\":\"High\",\"stufe_mittel\":\"Medium\",\"stufe_niedrig\":\"Low\",\"stufe_info\":\"Information\",\"stufe_gut\":\"In order\",\"keine_befunde\":\"Nothing to report.\",\"fehler_kein_token\":\"The check could not be started because reCAPTCHA did not load.\",\"fehler_captcha\":\"reCAPTCHA classified the request as automated. Reloading the page normally helps.\",\"fehler_zu_viele\":\"The limit of {limit} checks per hour for this address has been reached.\",\"fehler_adresse\":\"That address cannot be used.\",\"fehler_zaehler\":\"The rate counter is unavailable, so nothing was checked.\",\"fehler_pruefdienst\":\"The reCAPTCHA service could not be reached.\",\"fehler_aufbau\":\"The service is not configured correctly. The fault is on this side.\",\"fehler_eingabe\":\"The request could not be read.\",\"fehler_methode\":\"Wrong request method.\",\"fehler_netz\":\"The service could not be reached.\",\"fehler_antwort\":\"The answer could not be read.\",\"fehler_unbekannt\":\"Something went wrong that has no message of its own.\",\"grund_leer\":\"Nothing was entered.\",\"grund_keine_ip\":\"That is not an IPv4 or IPv6 address.\",\"grund_gesperrter_bereich\":\"The address lies in a private or reserved range; no public crawler comes from there.\",\"befund_ptr_fehlt\":\"No reverse DNS name for {ip} || Every serious crawler operator sets a PTR record. Its absence does not prove a forgery, but it removes the first and cheapest proof.\",\"befund_fcrdns_ok\":\"Reverse DNS is forward-confirmed: {ptr} || The PTR name resolves back to the same address. Only the owner of that domain can arrange that; a PTR alone could be set by whoever controls the reverse zone.\",\"befund_fcrdns_fehlt\":\"Reverse DNS not forward-confirmed: {ptr} resolves to {ips} || The PTR name points elsewhere, so it proves nothing. Operators\\u0027 own guidance (Google, Microsoft) requires both directions to match.\",\"befund_rdns_crawler\":\"Reverse DNS under the operator domain {domain}: {name} || A forward-confirmed name under this domain is the verification method the operator itself documents.\",\"befund_rdns_crawler_unbestaetigt\":\"Reverse DNS claims {domain}, but does not resolve back || The PTR name {ptr} suggests {name}, yet the forward lookup does not return this address. That is exactly how a forged PTR looks.\",\"befund_bereich_treffer\":\"Listed in {liste} ({betreiber}): {prefix} || The address lies in a range the operator publishes for this crawler. This is the strongest proof available.\",\"befund_liste_fehlt\":\"List(s) not loaded: {liste} || The operator\\u0027s list could not be fetched and no cached copy exists, so a claim for this crawler cannot be confirmed from ranges right now.\",\"befund_listen_stand\":\"{n} range lists loaded, as of {datum} || The lists are refreshed once a day. An address the operator added since then may be missing until the next refresh.\",\"befund_rdap\":\"Network: {name}, {org}, {bereich} ({land}) || Who the address is allocated to, from the regional registry via RDAP.\",\"befund_rechenzentrum\":\"Allocated to a hosting or cloud provider: {anbieter} || Real search crawlers run on their operators\\u0027 own networks. A crawler claim from a rented machine is almost always a scraper wearing the name. Google Cloud customers, for instance, are not Googlebot.\",\"befund_rdap_fehlt\":\"RDAP query failed ({grund}) || The network owner could not be determined this time.\",\"befund_behauptung_bestaetigt\":\"{name} confirmed ({weg}) || The address meets the operator\\u0027s published verification method.\",\"befund_behauptung_unpruefbar\":\"{name} publishes no verification method || Neither address ranges nor a reverse DNS convention exist for this operator, so the claim can only be judged by the network owner and by behaviour.\",\"befund_behauptung_widerlegt\":\"Claim refuted: not {name} (recognised as: {erkannt}; hosting: {rz}) || The operator publishes how to recognise its crawler, and this address meets none of it. Requests with this User-Agent from this address can be blocked without losing the real crawler.\",\"befund_erkannt_als\":\"Recognised as {liste} || Without a claim, the address was matched against every known operator.\",\"befund_nicht_erkannt\":\"{ip} matches no known crawler || Not in any published list and no operator reverse DNS. A claim of being a major search crawler from this address would be false.\"};<\/p>\n<p>    var ENDPUNKT = '\/lw-crawlerip.php';\n    var SITEKEY = '6LcrPkEtAAAAAPo1QCOf-IIM2fCL0UfdJz4y2iSY';\n    var STUFEN = ['hoch', 'mittel', 'niedrig', 'info', 'gut'];\n    var ERGEBNISSE = ['echt', 'gefaelscht', 'unpruefbar', 'erkannt', 'unbekannt'];<\/p>\n<p>    function liste(w) { return Array.isArray(w) ? w : []; }\n    function zahl(w) { return (typeof w === 'number' && isFinite(w)) ? w : null; }\n    function text(schluessel, daten) {\n        var t = T[schluessel];\n        if (typeof t !== 'string') { return null; }\n        return t.replace(\/\\{([a-z_0-9]+)\\}\/g, function (m, k) {\n            return (daten && daten[k] !== undefined && daten[k] !== null) ? String(daten[k]) : m;\n        });\n    }<\/p>\n<p>    function bewerten(antwort) {\n        var a = antwort || {};\n        if (a.fehler) { return { fehler: String(a.fehler), grund: a.grund || null, limit: zahl(a.limit) }; }\n        var befunde = liste(a.befunde).map(function (f) {\n            return { key: String(f.key || ''), stufe: STUFEN.indexOf(f.stufe) === -1 ? 'info' : f.stufe, daten: (f.daten && typeof f.daten === 'object') ? f.daten : {} };\n        });\n        var gruppen = {};\n        STUFEN.forEach(function (s) { gruppen[s] = befunde.filter(function (f) { return f.stufe === s; }); });\n        var rdap = (a.rdap && typeof a.rdap === 'object') ? a.rdap : null;\n        var treffer = (a.treffer && typeof a.treffer === 'object') ? a.treffer : {};\n        return {\n            fehler: null, ip: a.ip ? String(a.ip) : '',\n            urteil: (a.urteil === 'gut' || a.urteil === 'warnung' || a.urteil === 'kritisch') ? a.urteil : 'kritisch',\n            ergebnis: ERGEBNISSE.indexOf(a.ergebnis) === -1 ? 'unbekannt' : a.ergebnis,\n            behauptet: a.behauptet ? String(a.behauptet) : 'keine', behauptetName: a.behauptet_name ? String(a.behauptet_name) : '',\n            ptr: a.ptr ? String(a.ptr) : null, fcrdns: !!a.fcrdns, vorwaerts: liste(a.vorwaerts).map(String),\n            rdns: (a.rdns && typeof a.rdns === 'object') ? { name: String(a.rdns.name || ''), domain: String(a.rdns.domain || '') } : null,\n            treffer: Object.keys(treffer).map(function (k) { return { key: k, prefix: String(treffer[k]) }; }),\n            erkannt: liste(a.erkannt).map(String),\n            rdap: rdap ? { name: rdap.name ? String(rdap.name) : null, org: rdap.org ? String(rdap.org) : null, start: rdap.start ? String(rdap.start) : null, end: rdap.end ? String(rdap.end) : null, land: rdap.land ? String(rdap.land) : null, rechenzentrum: rdap.rechenzentrum ? String(rdap.rechenzentrum) : null } : null,\n            listen: liste(a.listen).map(function (l) { l = l || {}; return { key: String(l.key || ''), name: String(l.name || ''), betreiber: String(l.betreiber || ''), n: zahl(l.n) || 0, creationTime: l.creationTime ? String(l.creationTime) : null, fehler: l.fehler ? String(l.fehler) : null }; }),\n            listenStand: a.listen_stand ? String(a.listen_stand) : null,\n            befunde: befunde, gruppen: gruppen, dauer: zahl(a.dauer_ms), limitRest: zahl(a.limit_rest)\n        };\n    }<\/p>\n<p>    function skriptLaden() {\n        return new Promise(function (auf) {\n            if (window.grecaptcha) { auf(true); return; }\n            var s = document.createElement('script');\n            s.src = 'https:\/\/www.google.com\/recaptcha\/api.js?render=' + SITEKEY;\n            s.onload = function () { auf(true); }; s.onerror = function () { auf(false); };\n            document.head.appendChild(s);\n            setTimeout(function () { auf(!!window.grecaptcha); }, 8000);\n        });\n    }\n    function tokenHolen() {\n        return skriptLaden().then(function (da) {\n            if (!da || !window.grecaptcha || !window.grecaptcha.ready) { return null; }\n            return new Promise(function (auf) {\n                var fertig = false;\n                function einmal(w) { if (!fertig) { fertig = true; auf(w); } }\n                setTimeout(function () { einmal(null); }, 12000);\n                try {\n                    window.grecaptcha.ready(function () {\n                        if (fertig) { return; }\n                        if (!window.grecaptcha.execute) { einmal(null); return; }\n                        window.grecaptcha.execute(SITEKEY, { action: 'crawlerip' }).then(function (t) { einmal(t || null); }, function () { einmal(null); });\n                    });\n                } catch (e) { einmal(null); }\n            });\n        }, function () { return null; });\n    }\n    function abfragen(ip, behauptet) {\n        return tokenHolen().then(function (token) {\n            return fetch(ENDPUNKT, { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ ip: ip, behauptet: behauptet, token: token || '' }) })\n                .then(function (r) { return r.json().then(function (j) { return j; }, function () { return { fehler: 'antwort' }; }); }, function () { return { fehler: 'netz' }; });\n        });\n    }<\/p>\n<p>    window.LW_TEST = window.LW_TEST || {};\n    window.LW_TEST.CI = { bewerten: bewerten, darstellen: null, text: text, ENDPUNKT: ENDPUNKT, STUFEN: STUFEN, ERGEBNISSE: ERGEBNISSE, T: T };<\/p>\n<p>    var btn = document.getElementById('ci-btn');\n    var out = document.getElementById('ci-ausgabe');\n    if (!btn || !out) { return; }<\/p>\n<p>    function el(tag, stil, txt) { var e = document.createElement(tag); if (stil) { e.setAttribute('style', stil); } if (txt !== undefined && txt !== null) { e.textContent = txt; } return e; }\n    function wert(id) { var e = document.getElementById(id); return e ? e.value : ''; }\n    var UEBERSCHRIFT = 'font-family: \"Nunito Sans\", sans-serif; font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.95rem; margin: 22px 0 8px;';\n    var ZELLE = 'padding: 5px 12px 5px 0; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem;';\n    var ZELLE_WERT = 'padding: 5px 12px 5px 0; color: var(--text-primary, #e8e8ee); font-size: 0.87rem; font-family: monospace; word-break: break-all;';\n    var KASTEN = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 8px; padding: 14px 16px; margin: 0 0 10px;';\n    var GUT = ' color: #7ee787;', WARN = ' color: #ffa94d;', ROT = ' color: #ff7b72;', GRAU = ' color: #8a8a99;';\n    var FARBEN = { hoch: '#ff7b72', mittel: '#ffa94d', niedrig: '#e3b341', info: '#8a8a99', gut: '#7ee787' };\n    var URTEIL = { gut: GUT, warnung: WARN, kritisch: ROT };\n    var ERG_FARBE = { echt: GUT, gefaelscht: ROT, unpruefbar: GRAU, erkannt: GUT, unbekannt: '' };\n    function gitter(sp) { return el('div', 'display: grid; grid-template-columns: ' + sp + '; gap: 0 18px; align-items: baseline;'); }\n    function paar(g, n, w, stil) { g.appendChild(el('div', ZELLE, n)); g.appendChild(el('div', ZELLE_WERT + (stil || ''), w)); }<\/p>\n<p>    function darstellen(b, ziel) {\n        ziel.innerHTML = '';\n        if (b.fehler) {\n            var txt = T['fehler_' + b.fehler] || T.fehler_unbekannt;\n            if (b.grund && T['grund_' + b.grund]) { txt = txt + ' ' + T['grund_' + b.grund]; }\n            if (b.limit !== null) { txt = txt.replace('{limit}', String(b.limit)); }\n            ziel.appendChild(el('p', ZELLE + WARN + ' margin: 0;', txt));\n            return;\n        }\n        ziel.appendChild(el('div', 'font-size: 1.05rem; font-weight: 700; margin: 0 0 6px;' + ERG_FARBE[b.ergebnis], text('ergebnis_' + b.ergebnis, { name: b.behauptetName || '-', ip: b.ip, erkannt: b.erkannt.join(', ') || '-' })));\n        ziel.appendChild(el('p', ZELLE + ' margin: 0 0 12px; line-height: 1.55;', T['ergebnis_' + b.ergebnis + '_erklaerung']));<\/p>\n<p>        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_belege));\n        var g = gitter('auto auto');\n        paar(g, T.zeile_ip, b.ip);\n        if (b.behauptet !== 'keine') { paar(g, T.zeile_behauptet, b.behauptetName); }\n        paar(g, T.zeile_ptr, b.ptr || T.wert_keiner, b.ptr ? '' : GRAU);\n        if (b.ptr) { paar(g, T.zeile_vorwaerts, b.fcrdns ? T.vorwaerts_ok : text('vorwaerts_fehlt', { ips: b.vorwaerts.join(', ') || '-' }), b.fcrdns ? GUT : ROT); }\n        paar(g, T.zeile_rdns, b.rdns ? text('rdns_kurz', { name: b.rdns.name, domain: b.rdns.domain }) : T.wert_keiner, b.rdns ? (b.fcrdns ? GUT : ROT) : GRAU);\n        paar(g, T.zeile_listen, b.treffer.length ? b.treffer.map(function (t) { var l = b.listen.filter(function (x) { return x.key === t.key; })[0]; return (l ? l.name : t.key) + ' (' + t.prefix + ')'; }).join(', ') : T.wert_keiner, b.treffer.length ? GUT : GRAU);\n        if (b.rdap) {\n            paar(g, T.zeile_netz, (b.rdap.name || '-') + (b.rdap.org ? ' \u2013 ' + b.rdap.org : '') + (b.rdap.land ? ' (' + b.rdap.land + ')' : ''), GRAU);\n            if (b.rdap.start && b.rdap.end) { paar(g, T.zeile_bereich, b.rdap.start + ' \u2013 ' + b.rdap.end, GRAU); }\n            if (b.rdap.rechenzentrum) { paar(g, T.zeile_rechenzentrum, b.rdap.rechenzentrum, WARN); }\n        }\n        if (b.dauer !== null) { paar(g, T.zeile_dauer, b.dauer + ' ms', GRAU); }\n        if (b.limitRest !== null) { paar(g, T.zeile_limit, String(b.limitRest), GRAU); }\n        ziel.appendChild(g);<\/p>\n<p>        if (b.listen.length) {\n            ziel.appendChild(el('div', UEBERSCHRIFT, T.h_listen + (b.listenStand ? ' (' + text('listen_stand', { datum: b.listenStand }) + ')' : '')));\n            var huelle = el('div', 'overflow-x: auto;');\n            var gp = gitter('auto auto auto auto');\n            [T.spalte_liste, T.spalte_betreiber, T.spalte_praefixe, T.spalte_treffer].forEach(function (s) { gp.appendChild(el('div', ZELLE + ' font-weight: 700; color: var(--text-primary, #e8e8ee); white-space: nowrap;', s)); });\n            b.listen.forEach(function (l) {\n                var tr = b.treffer.filter(function (t) { return t.key === l.key; })[0];\n                gp.appendChild(el('div', ZELLE_WERT + ' white-space: nowrap;', l.name));\n                gp.appendChild(el('div', ZELLE_WERT + GRAU, l.betreiber));\n                gp.appendChild(el('div', ZELLE_WERT + (l.n ? GRAU : ROT), l.n ? String(l.n) : (l.fehler ? T.liste_nicht_geladen : '0')));\n                gp.appendChild(el('div', ZELLE_WERT + (tr ? GUT : GRAU), tr ? tr.prefix : '\u2013'));\n            });\n            huelle.appendChild(gp);\n            ziel.appendChild(huelle);\n        }<\/p>\n<p>        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_befunde));\n        var irgendwas = false;\n        STUFEN.forEach(function (s) {\n            var gr = b.gruppen[s];\n            if (!gr.length) { return; }\n            irgendwas = true;\n            ziel.appendChild(el('div', 'font-weight: 700; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.5px; margin: 14px 0 6px; color: ' + FARBEN[s] + ';', T['stufe_' + s] + ' (' + gr.length + ')'));\n            gr.forEach(function (f) {\n                var k = el('div', KASTEN + ' border-left: 3px solid ' + FARBEN[s] + ';');\n                var t = text('befund_' + f.key, f.daten) || f.key;\n                var teile = t.split(' || ');\n                k.appendChild(el('div', 'color: var(--text-primary, #e8e8ee); font-size: 0.9rem; font-weight: 700;', teile[0]));\n                if (teile[1]) { k.appendChild(el('div', ZELLE + ' padding: 6px 0 0; line-height: 1.55;', teile[1])); }\n                ziel.appendChild(k);\n            });\n        });\n        if (!irgendwas) { ziel.appendChild(el('p', ZELLE + ' margin: 0;', T.keine_befunde)); }\n    }\n    window.LW_TEST.CI.darstellen = darstellen;<\/p>\n<p>    var laeuft = false;\n    btn.addEventListener('click', function () {\n        if (laeuft) { return; }\n        laeuft = true; btn.disabled = true;\n        out.innerHTML = '';\n        out.appendChild(el('p', ZELLE + GRAU + ' margin: 0;', T.laeuft));\n        abfragen(wert('ci-ip'), wert('ci-behauptet')).then(function (a) { darstellen(bewerten(a), out); laeuft = false; btn.disabled = false; },\n            function () { darstellen(bewerten({ fehler: 'netz' }), out); laeuft = false; btn.disabled = false; });\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Takes an IP address from a server log and checks whether it really belongs to the crawler it claims to be: reverse DNS with forward confirmation, the address lists Google, Microsoft, OpenAI, Apple, Perplexity and Ahrefs publish, and the network owner from RDAP.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":38,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[91243,91094,91115],"class_list":["post-15558","page","type-page","status-publish","hentry","tag-networking","tag-seo","tag-web-security"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Takes an IP address from a server log and checks whether it really belongs to the crawler it claims to be: reverse DNS with forward confirmation, the address lists Google, Microsoft, OpenAI, Apple, Perplexity and Ahrefs publish, and the network owner from RDAP.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-05T13:08:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/crawler-ip-verifier-googlebot-bingbot-gptbot\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/crawler-ip-verifier-googlebot-bingbot-gptbot\\\/\",\"name\":\"Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-09-05T12:11:00+00:00\",\"dateModified\":\"2026-09-05T13:08:37+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/crawler-ip-verifier-googlebot-bingbot-gptbot\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/crawler-ip-verifier-googlebot-bingbot-gptbot\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/crawler-ip-verifier-googlebot-bingbot-gptbot\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/","og_locale":"en_US","og_type":"article","og_title":"Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others - Lukas Wojcik - Blog","og_description":"Takes an IP address from a server log and checks whether it really belongs to the crawler it claims to be: reverse DNS with forward confirmation, the address lists Google, Microsoft, OpenAI, Apple, Perplexity and Ahrefs publish, and the network owner from RDAP.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-09-05T13:08:37+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/","name":"Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-09-05T12:11:00+00:00","dateModified":"2026-09-05T13:08:37+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/crawler-ip-verifier-googlebot-bingbot-gptbot\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/"},{"@type":"ListItem","position":3,"name":"Crawler IP Verifier: Googlebot, Bingbot, GPTBot and Others"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15558","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=15558"}],"version-history":[{"count":1,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15558\/revisions"}],"predecessor-version":[{"id":15579,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15558\/revisions\/15579"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/38"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=15558"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=15558"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}