整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

vite中获取某指定的文件目录

vite中获取某指定的文件目录

在某个文件中需要引用某个文件夹下的所有js文件。这种情况在使用webpack搭建的项目中使用下面的方法即可获取到:

const modules=require.context(
  './', // 在当前目录下查找
  true, // 遍历子文件夹
  /\.js$/ // 正则匹配 以 .vue结尾的文件
)

但是,在使用vite搭建的vue3.x的项目里面是不能使用上面的这个方法的。因为require.context这个方法是由webpack所提供的,但vite并不提供这个方法。那该如何解决呢?

解决

vite的官方网站其实是给出了类似的功能方法的。可以使用其提供的Glob 导入(https://vitejs.cn/guide/features.html#glob-import),使用方法如下:

// 指定包含的文件
const modules=import.meta.glob('./dir/*.js')

最后生成的效果:

、BeautifulSoup简介

BeautifulSoup是Python爬虫应用解析Html的利器,是Python三方模块bs4中提供的进行HTML解析的类,可以认为是一个HTML解析工具箱,对HTML报文中的标签具有比较好的容错识别功能。lxml是一款html文本解析器,BeautifulSoup构建对象时需要指定HTML解析器,推荐使用lxml。

BeautifulSoup和lxml安装命令:

1.pip install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4

2.pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lxml

加载BeautifulSoup

1.from bs4 import BeautifulSoup

BeatifulSoap解析HTML报文的常用功能

  1. 通过BeautifulSoup对象可以访问标签对应的html元素、并进一步访问标签的名字、属性、html元素标签对中的内容。
    案例from bs4 import BeautifulSoup
  2. import urllib.request
  3. def getURLinf(url):
  4. header={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'}
  5. req=urllib.request.Request(url=url,headers=header)
  6. resp=urllib.request.urlopen(req,timeout=5)
  7. html=resp.read().decode()

  8. soup=BeautifulSoup(html,'lxml')
  9. return (soup,req,resp)

  10. soup,req ,resp=getURLinf
  11. print(soup.p)
  12. print(soup.link)
  13. print(soup.title)
  14. print(soup.link.attrs)
  15. print(soup.link['rel'])

通过标签的contents属性,可以访问其下嵌套的所有下级HTML元素,这些该标签下的子标签对应的HTML元素放到一个contents 指向的列表中。

如:print(soup.body.contents)

可以访问标签对应的父、子、兄弟及祖先标签信息;

使用strings属性迭代访问除标签外的所有内容;

可以使用find、find_all、find_parent、find_parents等系列方法查找满足特定条件的标签;

使用select通过css选择器定位特定标签。


二、一些解析技巧

在HTML解析时,如果通过简单的tag、或单个tag属性(如id、class)或文本一次搜索或select定位是最简单的,而有些情况需要使用组合方法才能处理。

2.1、通过标签的多个属性组合定位或查找

经常有些要定位的标签有很多,按单个属性查找也有很多,得使用多个属性查找。如:

上面的html文本中有多个id为article_content的div标签,如果使用:

  1. >>> text="""```html
  2. <div id="article_content" class="article_content clearfix">
  3. ......
  4. </div>
  5. <div id="article_content" class="article_view">
  6. ......
  7. </div>
  8. <div id="article_view" class="article_view">
  9. ......
  10. </div>"""
  11. >>> s=BeautifulSoup(text,'lxml')
  12. >>> s.select('div#article_content')
  13. [<div class="article_content clearfix" id="article_content">......</div>,
  14. <div class="article_view" id="article_content">......</div>]
  15. >>>


就会返回两条记录。这时候就可以使用多标签属性定位的如下4种语句:

  1. >>>s.select('div#article_content[class="article_content clearfix"]')
  2. [<div class="article_content clearfix" id="article_content">......</div>]
  3. >>>s.select('div[id="article_content"][class="article_content clearfix"]')
  4. [<div class="article_content clearfix" id="article_content">......</div>]
  5. >>>s.find_all("div",id="article_content",class_='article_content clearfix')
  6. [<div class="article_content clearfix" id="article_content">......</div>]
  7. >>>s.find_all("div","#article_content",class_='article_content clearfix')
  8. [<div class="article_content clearfix" id="article_content">......</div>]


以上四种方式是等价的,因为id可以用#来标记,class在查找时需要和Python关键字class区分,因此有上述不同方法,注意select的每个属性必须用中括号括起来,不同属性的中括号之间不能有空格,如果有空格表示的就不是查找同一标签的属性,空格后的属性表示前一个属性对应标签的子孙标签的属性。


2.2、利用tag标签关系定位内容

tag标签关系包括父子、兄弟、祖先等关系,有时要查找或定位的内容本身不是很好定位,但结合其他标签关系(主要是父子、祖先关系)则可以唯一确认。

案例:

这是博文中关于博主个人信息的部分报文:

  1. <div class="data-info d-flex item-tiling">
  2. <dl class="text-center" title="1055">
  3. <a href=" " data-report-click='{"mod":"1598321000_001","spm":"1001.2101.3001.4310"}' data-report-query="t=1">
  4. <dt><span class="count">1055</span></dt>
  5. <dd class="font">原创</dd>
  6. </a>
  7. </dl>
  8. <dl class="text-center" data-report-click='{"mod":"1598321000_002","spm":"1001.2101.3001.4311"}' title="22">
  9. <a href=" " target="_blank">
  10. <dt><span class="count">22</span></dt>
  11. <dd class="font">周排名</dd>
  12. </a>
  13. </dl>
  14. </div>


以上报文中,如果要取博主的原创文章数和周排名,原创文章数和博主周排名的tag标签完全相同,二者都在span标签内,标签的属性及值都相同,只是span标签的父标签dt标签的兄弟标签dd标签的string的中文内容才能区分。对于这种情况,首先要通过祖先标签<div class="data-info d-flex item-tiling">定位到祖先标签,再在祖先标签内通过中文字符串定位到要访问属性的兄弟标签的子标签,然后通过该子标签找到其父标签的父标签,再通过该父标签的dt子标签的span子标签访问具体取值。

示例代码如下:

  1. >>> text="""
  2. <div class="data-info d-flex item-tiling">
  3. <dl class="text-center" title="1055">
  4. <a href=" " data-report-click='{"mod":"1598321000_001","spm":"1001.2101.3001.4310"}' data-report-query="t=1">
  5. <dt><span class="count">1055</span></dt>
  6. <dd class="font">原创</dd>
  7. </a>
  8. </dl>
  9. <dl class="text-center" data-report-click='{"mod":"1598321000_002","spm":"1001.2101.3001.4311"}' title="22">
  10. <a href=" " target="_blank">
  11. <dt><span class="count">22</span></dt>
  12. <dd class="font">周排名</dd>
  13. </a>
  14. </dl>
  15. </div>"""
  16. >>> s=BeautifulSoup(text,'lxml')
  17. >>> subSoup=s.select('[class="data-info d-flex item-tiling"] [class="font"]')
  18. >>> for item in subSoup:
  19. parent=item.parent
  20. if item.string=='原创':
  21. orignalNum=int(parent.select('.count')[0].string)
  22. elif item.string=='周排名':
  23. weekRank=int(parent.select('.count')[0].string)

  24. >>> print(orignalNum,weekRank)
  25. 1055 22
  26. >>>


注意:上面的select使用的也是标签的属性来定位标签,并且两个中括号之间有空格,表明后一个要查找的标签在前一个属性对应标签的子孙标签范围内。

2.3、分析前去除程序代码避免干扰

在解析HTML报文时,绝大多数情况是需要分析有用的标签信息,但作为技术文章,大部分的博文中都有代码,这些代码可能会对分析进行干扰。如本文中的代码含有一些分析的HTML报文,如果获取本文的完整HTML内容,这些报文在非代码部分也会出现,此时要排除代码的影响,可以将代码先从分析内容中去除再来分析。

目前大多数技术平台的博文编辑器都支持对代码的标识,象markdown等编辑器代码的标签为code标检,如果有其他编辑器用不同标签的,只有确认了标签名,都可以按下面介绍的类似方式来处理。

处理步骤如下:

获取报文;

构建BeatifulSoap对象soup;

通过soup.code.extract()或soup.code.decompose()方式就从soup对象中去除了代码部分,decompose方法与extract方法的区别就是decompose直接删除对应对象数据而extract再删除时将删除对象单独返回。

三、小结

本文介绍了使用BeatifulSoap解析HTML报文的三个使用技巧,包括通过多属性组合查找或定位标签、通过结合多个标签关系来定位标签以及去除html报文中的代码标签来避免代码对解析的影响。

写字不易,敬请支持:

如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

————————————————

版权声明:本文为转载文章,如有侵权,请联系作者删除。

天想聊聊在Web前端开发中经常用到的技术:获取元素属性的一系列方法【innerHTML、outerHTML、innerText 、outerText、value、text()、html(),val()】

这些方法,大家应该用过,如果让你说出它们的一些区别和联系,能答得上来吗?接下来让我们一起来温故下。

首先我们需要把它们归类下:

innerHTML、outerHTML、innerText 、outerText、value 属于原生javascript的方法。

text()、html(),val()属于jQuery中的方法。

1、innerHTML 属性

在读模式下,innerHTML属性返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的 HTML 标记。在写模式下,innerHTML 会根据指定的值创建新的 DOM 树,然后用这个 DOM 树完全替换调用元素原先的所有子节点。下面是一个例子:


<div id="content">
 <p>This is a <strong>paragraph</strong> with a list following it.</p>
 <ul>
 <li>Item 1</li>
 <li>Item 2</li>
 <li>Item 3</li>
 </ul>
</div>

对于上面的<div>元素来说,它的 innerHTML 属性会返回如下字符串。


<p>This is a <strong>paragraph</strong> with a list following it.</p>
<ul>
 <li>Item 1</li>
 <li>Item 2</li>
 <li>Item 3</li>
</ul>


2、outerHTML 属性

在读模式下,outerHTML 返回调用它的元素及所有子节点的 HTML 标签。在写模式下,outerHTML 会根据指定的 HTML 字符串创建新的 DOM 子树完全替换调用元素。下面是一个例子。


<div id="content">
 <p>This is a <strong>paragraph</strong> with a list following it.</p>
 <ul>
 <li>Item 1</li>
 <li>Item 2</li>
 <li>Item 3</li>
 </ul>
</div>

如果在<div>元素上调用 outerHTML,会返回与上面相同的代码,包括<div>本身。

使用 outerHTML 属性以下面这种方式设置值:


div.outerHTML="<p>This is a paragraph.</p>";

这行代码完成的操作与下面这些 DOM 脚本代码一样:


var p=document.createElement("p");
p.appendChild(document.createTextNode("This is a paragraph."));
div.parentNode.replaceChild(p, div);

结果,就是新创建的<p>元素会取代 DOM 树中的<div>元素。

replaceChild() 方法用新节点替换某个子节点。

语法:


node.replaceChild(newnode,oldnode)

3、innerText 属性

通过 innerText 属性可以操作元素中包含的所有文本内容,包括子文档树中的文本。在通过 innerText 读取值时,它会按照由浅入深的顺序,将子文档树中的所有文本拼接起来。在通过 innerText 写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点。下面是一个例子:


<div id="content">
<p>This is a <strong>paragraph</strong> with a list following it.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>

对于这个例子中的 <div> 元素而言,其中 innerText 属性会返回下列字符串:


This is a paragraph with a list following it.
Item 1
Item 2
Item 3

使用 innerText 属性设置这个<div>元素内容,则只需一行代码:


div.innerText="Hello world!";

执行这行代码后,页面的 HTML 代码就会变成如下所示:


<div id="content">Hello world!</div>

设置 innerText 属性移除了先前存在的所有子节点,完全改变了 DOM 树。

设置 innerText 永远只会生成当前节点的一个子文本节点,而为了确保只生成一个字文本节点,就必须要对文本进行 HTML 编码。利用这一点,可以通过 innerText 属性过滤掉 HTML 标签。方法是将 innerText 设置等于 innerText,这样就可以去掉所有 HTML 标签,比如:


div.innerText=div.innerText;

执行这行代码后,就用原来的文本内容替换了容器元素中的所有内容(包括子节点,因而也就去掉了 HTML 标签)。举个栗子:


<label id="lab">请输入北京今天空气质量:<input id="aqi-input" type="text"></label>

输出:

4、outerText 属性

除了作用范围扩大到了包含 调用它的节点之外,outerText 与innerText 基本上没有多大区别。在读取文本值时,outerText 与 innerText 的结果完全一样。但在写模式下,outerText 就完全不同了:outerText 不只是替换调用它的元素的子节点,而是会替换整个元素(包括子节点)。比如:


div.outerText="Hello world!";

这行代码实际上相当于如下两行代码:


var text=document.createTextNode("Hello world!");
div.parentNode.replaceChild(text,div);

本质上,新的文本节点会完全取代调用 outerText 的元素。此后,该元素就从文档中被删除,无法访问。

5、value 属性

属性可设置或返回密码域的默认值。获取文本框的值。

6、text():设置或者获取所选元素的文本内容

1)无参text():

取得所有匹配元素的内容。结果是由所有匹配元素包含的文本内容组合起来的文本。返回的是一个String。

2)有参text(val):

设置所有匹配元素的文本内容,与 html() 类似, 但将编码 HTML (将 "<" 和 ">" 替换成相应的HTML实体).返回一个jquery对象。

7、html():设置或者获取所选元素的内容(包括html标记)

1)无参html():

取得第一个匹配元素的html内容。这个函数不能用于XML文档。但可以用于XHTML文档,返回的是一个String。

2)有参html(val):

设置每一个匹配元素的html内容。这个函数不能用于XML文档。但可以用于XHTML文档。返回一个jquery对象。

8、val()方法

主要用于获取表单元素的值如input, select 和 textarea。当在一个空集合上调用,它返回undefined;

1)无参 val() :

获取匹配的元素集合中第一个元素的当前值。例子:

HTML代码:


<input type="text" value="你好啊">
<input type="text" value="啊哈哈哈">
<input type="text" value="嘻嘻嘻嘻">

控制台输出:

2)有参val(val):

设置每一个匹配元素的值。返回一个jquery对象。

总结

对于这八大方法:innerHTML、outerHTML、innerText 、outerText、value、text()、html(),val()。您现在是否已经很清晰了?

我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。

原文链接:https://mp.weixin.qq.com/s/K7SyPeuZedmuj-a4HwoYfQ

作者: 前端大牛爱好者