浏览器抓取网页(网页开发时需要操作相同类名的元素,不足之处的方法)

优采云 发布时间: 2021-12-15 20:03

  浏览器抓取网页(网页开发时需要操作相同类名的元素,不足之处的方法)

  在网页开发中,我们经常需要对具有相同类名的元素进行操作,即具有相同类名的元素。在昨天的笔试中,我没有回答一个相关的问题:

  JavaScript获取页面中带有类test的节点

  因此,本文采集了一些相关资料,列举了两种较好的方法和不足之处。我希望你能批评和纠正他们。如果你有更好的方法,我希望你能分享

  解决方案1 Jeremy keuth解决方案

  Jeremy keuth叔叔在《JavaScript DOM编程艺术》(第二版)(英文:使用JavaScript和文档对象模型编写DOM脚本的web设计)第3章第4节中谈到了getelementsbyclass方法,以及如何在不支持此属性的浏览器(IE6、IE7和IE8,让我们瞧不起它们)中使用此方法,此处摘录并在某些地方进行了修改

  HTML5DOM中的一个新方法允许我们通过class属性中的类名访问元素,即getelementsbyclassname。由于该方法相对较新,因此在某些DOM实现中不可用,因此在使用它时应小心。让我们看看这个方法能为我们做什么,然后讨论如何可靠地使用这个方法

  与getElementsByTagName方法类似,getelementsbyclassname只接受一个参数,即类名:

  副本代码如下:

  getElementsByClassName(类)

  此方法的返回值类似于getElementsByTagName。它是具有相同类名的元素数组。以下代码行返回一个数组,其中收录类名为“sale”的所有元素:

  副本代码如下:

  文件。getElementsByClassName(“销售”)

  使用此方法,还可以查找具有多个类名的元素。要指定多个类名,只需在字符串参数中用空格分隔类名。例如,在

  您将在警告框中看到1,表示只有一个元素匹配,因为只有一个元素同时具有“重要”和“销售”类名。请注意,即使元素的class属性中类名的顺序是“sale-important”,而不是参数中指定的“重要sale”,元素仍将匹配。不仅类名的实际顺序无关紧要,元素是否有更多的类名也无关紧要。与getElementsByTagName一样,getelementsbyclassname和getelementbyid可以组合使用。如果您想知道ID为purchase的元素中有多少类名收录test的列表项,可以先找到特定的对象,然后调用getelementsbyclassname:

  副本代码如下:

  var购物=文档。getElementById(“购买”)

  var销售=购物。getElementsByClassName(“出售”)

  这样,sales数组只收录“purchase”列表中具有“sales”类的元素。运行以下代码行以查看sales数组收录两项:

  副本代码如下:

  警报(sales.length)

  这个getElementsByCassName方法非常有用,但它只受较新浏览器(Safari3.1、chorme、Firefox 3和opera9.5及更高版本)的支持。为了弥补这一不足,DOM脚本程序员需要使用现有的DOM方法来实现他们自己的GetElementsByCassName,这有点像成年礼。在大多数情况下,它们的实现过程大致类似于下面的getelementsbyclassname。此功能可应用于新浏览器和旧浏览器

  副本代码如下:

  函数getElementsByClassName(节点,类名){

  if(node.getElementsByClassName){

  返回节点。getElementsByClassName(类名称)

  }否则{

  var结果=[]

  var elems=节点。getElementsByTagName(“*”)

  for(var i=0;i if(elems[i].className.indexOf(className)!=-1){

  结果[结果.长度]=元素[i]

  }

  }

  返回结果

  }

  }

  getelementsbyclassname函数接受两个参数。第一个节点表示DOM树中的搜索起点,第二个类名是要搜索的类名。如果传入节点上已经存在相应的getelementsbyclassname函数,则新函数将直接返回相应的节点列表。如果getElementsByCassName函数不存在,新函数将遍历所有标记以查找具有相应类名的元素

  此方法的缺点是它不适用于多个类名

  如果您使用此函数模拟之前获取购物清单的操作,则可以编写如下:

  副本代码如下:

  var购物=文档。getElementById(“购买”)

  var销售=购物。getElementsByClassName(购物,“测试”)

  控制台。日志(销售)

  因此,要解决文章开头的问题,代码如下:

  副本代码如下:

  买什么

  别忘了买这东西

  解决方案2罗伯特·尼曼解决方案

  有许多方法可以搜索匹配的DOM元素,但很少有真正有效的方法。Jeremy keuth叔叔的方法有一个缺点,即它不能用于多个类名。2008年,Robert Nyman在文章最终的getelements byclassname中提供了自己的解决方案,anno 2008。2005年,罗伯特叔叔给出了他自己的getelementsbyclassname函数。2008年,他修改了一些代码并添加了许多新功能:

  1.如果当前浏览器支持GetElementsByCassName函数,请调用本机函数

  2.如果当前浏览器支持XPath,请使用它//Little flying fish:查找浏览器中内置的XML文档的强大方法,但浏览器支持并不统一

  3.支持搜索多个类名,而不考虑顺序

  4.返回一个真实的节点数组,而不是本机节点列表//Little flying fish:本机getElementsByCassName方法返回一个类似于数组的节点列表对象。它具有长度和数字索引属性,但不是数组。无法使用特定于数组的方法,如pop和push。在Robert提供的代码中,NodeList对象被转换为数组。将节点列表对象转换为数组的方法:

  副本代码如下:

  myList=数组。原型片呼叫(myNodeList)

  这是罗伯特叔叔的方法。有些地方我不太懂。我会在研究之后更新它

  副本代码如下:

  /*

  由Robert Nyman开发

  代码/许可证:

  */

  var getElementsByClassName=函数(类名、标记、elm){

  if(document.getElementsByClassName){

  getElementsByCassName=函数(类名、标记、elm){

  elm=elm | |文件

  var元素=elm。getElementsByClassName(类名称)

  节点名=(标记)?新的RegExp(“\\b”+标记+”\\b,“i”):null

  returnElements=[]

  电流

  对于(var i=0,il=elements.length;icurrent=elements[i]

  如果(!nodeName | | nodeName.test(current.nodeName)){

  返回元素。推动(电流)

  }

  }

  返回元素

  })

  }

  else if(文档评估){

  getElementsByCassName=函数(类名、标记、elm){

  标记=标记| |“*”

  elm=elm | |文件

  var classes=className。拆分(“”)

  classesToCheck=“”

  xhtmlNamespace=“”

  namespaceResolver=(document.documentElement.namespaceURI==xhtmlNamespace)?xhtmlNamespace:null

  returnElements=[]

  元素

  节点

  对于(var j=0,jl=classes.length;jclassesToCheck+=”[收录(concat(“”,@class'),“+classes[j]+”)]”

  }

  试一试{

  元素=文档。求值(“./”+标记+classesToCheck,elm,namespacesolver,0,null)

  }

  捕获(e){

  元素=文档。求值(“./”+标记+classesToCheck,elm,null,0,null)

  }

  while((node=elements.iterateNext()){

  返回元素。推送(节点)

  }

  返回元素

  })

  }

  否则{

  getElementsByCassName=函数(类名、标记、elm){

  标记=标记| |“*”

  elm=elm | |文件

  var classes=className。拆分(“”)

  classesToCheck=[]

  元素=(标记==“*”&&elm.all)?榆树所有人:埃尔姆。getElementsByTagName(标记)

  现在,

  returnElements=[]

  匹配

  对于(var k=0,kl=classes.length;kclassesToCheck.push(新的RegExp(“(^ |\\s)”+classes[k]+”(\\s |$)))

  }

  对于(var l=0,ll=elements.length;LCCurrent=elements[l]

  匹配=假

  for(var m=0,ml=classesToCheck.length;mmatch=classesToCheck[m].test(current.className)

  如果(!匹配){

  中断

  }

  }

  如果(匹配){

  返回元素。推动(电流)

  }

  }

  返回元素

  })

  }

  返回getElementsByClassName(className,tag,elm)

  })

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线