так что я был в такой же ситуации, но с XML, и я создал этот анализатор HTML / XML для своих собственных нужд.
я пытался сделать так, чтобы это выглядело как модель манипулирования DOM в браузере, поэтому большинство вещей работает одинаково
Сначала просто скопируйте вставку в ваш js-файл.не забудьте объявить «используйте строгий»;в начале файла.
class Node {
constructor(nodeName, nodeType) {
this.nodeName = nodeName;
this.nodeType = nodeType;
this.attributes = {};
this.childNodes = [];
this.parentNode = null;
}
removeChild(node) {
if (node.parentNode != null) {
for (var i = 0; i < this.childNodes.length; i++) {
if (node == this.childNodes[i]) {
this.childNodes.splice(i, 1);
node.parentNode = null;
}
}
}
}
appendChild(child) {
if (child.parentNode == null) {
this.childNodes.push(child);
child.parentNode = this;
} else {
child.parentNode.removeChild(child);
this.childNodes.push(child);
child.parentNode = this;
}
}
returnMyChildNodes() {
return this.childNodes;
}
returnElementCollection() {
var array = [];
array.push(this);
for (var i = 0; i < this.childNodes.length; i++) {
var tmparray = [];
tmparray = this.childNodes[i].returnElementCollection();
array = array.concat(tmparray);
}
return array;
}
getELementsByAttributeValue(attribute, value) {
var matchedElements = [];
var Elements = this.returnElementCollection();
console.log(Elements.length);
for (var i = 0; i < Elements.length; i++) {
if (typeof Elements[i].attributes[attribute] != "undefined") {
if (Elements[i].attributes[attribute] == value) {
matchedElements.push(Elements[i]);
}
}
}
return matchedElements;
}
}
Этот объект узла будет действовать как HTML-узлы.поэтому мы объявляем еще один класс здесь.
class Html_Node extends Node {
constructor(name) {
super(name, "HTML_ELEMENT");
}
toString() {
}
}
class Xml_Node extends Node {
constructor(name) {
super(name, "XML_ELEMENT");
this.innerText = "";
}
}
после того, как у нас есть классы для обоих, мы переходим к сложной части. Читаем документ и строим наши узлы в 1 документе
class XML_Reader {
constructor() {
this.rawContents = "";
this.Document = null;
}
loadXML(documentPath) {
if (documentPath != null && documentPath != "") {
var fs = require("fs");
var fc = fs.readFileSync(documentPath, {
encoding: "utf-8"
});
if (typeof fc != "undefined" && fc != null) {
this.rawContents = fc;
} else {
this.rawContents = null;
}
delete require.cache[require.resolve("fs")];
} else {
this.rawContents = null;
}
}
processXML() {
var XML_DOC = new Xml_Node("root");
var rawElements = [];
var TagStart_index = 0;
var TagEnd_index = 0;
var innerContent_Start = 0;
var innerContent_End = 0;
for (var i = 0; i < this.rawContents.length; i++) {
// get starting tags
if (this.rawContents[i] == "<") {
TagStart_index = i;
innerContent_End = i - 1;
var innerContent = "";
if (innerContent_End > innerContent_Start) {
for (var n = innerContent_Start; n <= innerContent_End; n++) {
innerContent += this.rawContents[n];
}
if (/\S/.test(innerContent)) {
// do smth with innerContent of tag
rawElements.push(innerContent);
}
}
} else if (this.rawContents[i] == ">") {
TagEnd_index = i;
innerContent_Start = i + 1;
var contents = "";
for (var n = TagStart_index; n <= TagEnd_index; n++) {
contents += this.rawContents[n];
}
rawElements.push(contents);
}
}
var currentParent = XML_DOC;
for (var i = 0; i < rawElements.length; i++) {
if (/>/.test(rawElements[i]) && /</.test(rawElements[i])) {
if (rawElements[i].indexOf("/") == 1) {
currentParent = currentParent.parentNode;
} else {
var str = rawElements[i];
str = str.replace("<", "");
str = str.replace(">", "");
var IgnoreSpace = false;
var tempString = "";
var InnerNodeContents = [];
var wordIndex = 0;
for (var n = 0; n < str.length; n++) {
if (!IgnoreSpace) {
if (str[n] == "/") {
InnerNodeContents[wordIndex] = tempString;
tempString = "";
wordIndex++;
}
if (n + 1 == str.length) {
tempString +=
str[n];
InnerNodeContents[wordIndex] = tempString;
tempString = "";
wordIndex++;
} else if (!/\S/.test(str[n])) {
InnerNodeContents[wordIndex] = tempString;
tempString = "";
wordIndex++;
} else {
tempString += str[n];
}
if (str[n] == '"') IgnoreSpace = true;
} else {
if (str[n] == "/") {
InnerNodeContents[wordIndex] = tempString;
tempString = "";
wordIndex++;
}
if (n + 1 == str.length) {
tempString += str[n];
InnerNodeContents[wordIndex] = tempString;
tempString = "";
wordIndex++;
} else {
tempString += str[n];
}
if (str[n] == '"') IgnoreSpace = false;
}
}
var node = new Xml_Node(InnerNodeContents[0]);
// add attributes
var switchParent = false;
if (InnerNodeContents[InnerNodeContents.length - 1] == "/") {
switchParent = true;
for (var n = 1; n < InnerNodeContents.length - 1; n++) {
var tmparray = InnerNodeContents[n].split("=");
node.attributes[tmparray[0]] = tmparray[1].replaceAll('"', "");
}
} else {
for (var n = 1; n < InnerNodeContents.length; n++) {
var tmparray = InnerNodeContents[n].split("=");
node.attributes[tmparray[0]] = tmparray[1].replaceAll('"', "");
}
}
currentParent.appendChild(node);
if (!switchParent) currentParent = node;
}
} else {
currentParent.innerText = rawElements[i];
}
}
this.Document = XML_DOC;
}
}
, а затем все, что нам нужно сделать, это:
var xr = new XML_Reader();
xr.loadXML("Path to HTML file");
xr.processXML();
var Elements = xr.Document.getElementsByAttributeValue("class", "jd");
и теперь у вас есть элемент Everysingle с классом jd в этой переменной Element.
и затем, чтобы получить URL каждого из них, вы будете выполнять цикл FOR и получать атрибут href
var myUrl = Elements[0].attributes.href;
Я сделал этот скрипт для себя, поэтому не стесняйтесь использовать его:)
еще одна вещь.чтобы получить потомков DIV с классом JD, вам нужно получить этот div и найти nodeNames (a) и получить атрибуты наследника href.