网页抓取时xhr.onload报错无法读取null的querySelector属性求解
问题场景
实现前端网页抓取功能时,执行以下script.js代码抛出错误:Cannot read properties of null (reading 'querySelector') at xhr.onload,已确认CSS选择器写法无误。
document.addEventListener("DOMContentLoaded", function(){ const $prod = document.getElementById("prod"); const $precio = document.getElementById("precio"); let xhr = new XMLHttpRequest(); xhr.open("GET", "https://cors-anywhere.herokuapp.com/url", true); xhr.responseType = "document"; xhr.onload = function(){ /*if(xhr.readyState === 4 && xhr.status === 200){*/ let response = xhr.responseXML.querySelector(".className"); console.log(response); /*}*/ }; xhr.onerror = function(){ console.error(xhr.status, xhr.statusText); } xhr.send(); })
错误原因
报错指向xhr.responseXML为null,和CSS选择器逻辑无关,触发原因包括:
- 你把请求状态校验的代码注释掉了:
onload回调不代表请求成功,4xx/5xx请求异常、代理返回错误页时都会触发onload,此时响应内容不是目标页面,自然解析不出Document对象。 - 公共CORS代理未授权:你使用的cors-anywhere公共实例需要手动完成临时访问授权,未授权时会返回纯文本权限提示,无法被解析为XML/HTML文档对象。
- 响应头不匹配:如果目标页面返回的
Content-Type不是text/html/application/xhtml+xml类型,XHR不会自动将响应解析为Document对象,responseXML会直接返回null。
修复方案
- 恢复请求状态校验逻辑,增加空值判断,先确认请求和响应解析正常再执行DOM查询:
document.addEventListener("DOMContentLoaded", function(){ const $prod = document.getElementById("prod"); const $precio = document.getElementById("precio"); let xhr = new XMLHttpRequest(); xhr.open("GET", "https://cors-anywhere.herokuapp.com/你的目标页面地址", true); xhr.responseType = "document"; xhr.onload = function(){ // 校验请求状态 if(xhr.readyState !== 4 || xhr.status !== 200){ console.log("请求异常,状态码:", xhr.status, "原始响应:", xhr.responseText); return; } // 校验文档解析结果 if(!xhr.responseXML){ console.log("文档解析失败,原始响应:", xhr.responseText); return; } let response = xhr.responseXML.querySelector(".className"); console.log(response); }; xhr.onerror = function(){ console.error("网络请求错误", xhr.status, xhr.statusText); } xhr.send(); })
- 运行代码后查看控制台打印的原始响应内容:
- 如果返回cors-anywhere的权限提示,先完成代理的临时访问授权再重试
- 如果返回正常目标页HTML但仍提示解析失败,去掉
xhr.responseType = "document"配置,手动用DOMParser将xhr.responseText解析为Document对象后再做DOM查询即可。
内容的提问来源于stack exchange,提问作者Vanesa Morilla
相关产品推荐
相关产品推荐

