一、网页的组成
网页可以分为三大部分——HTML,CSS 和 JavaScript
1、HTML
HTML:一种用来描述网页的语言——超文本标记语言(Hyper Text Markup Language)。网页包括了文字,土图片,视频和按钮等复杂的元素,其中基础框架就是HTML。不同的元素通过不同的标签来表示,例如:图片img,视频video,段落p,一级标题h1 等。他们之间的分布通常又由 div 嵌套组合而成,通过标签的排序和嵌套才形成了网页框架。
2、CSS
CSS:一个网页排版工具——层叠样式表(Cascading Style Sheets)。即当在HTML中引用了数个样式(文字大小,颜色,元素间距,排列等格式)文件并且发生冲突时,浏览器能依据层叠顺序进行处理。以下给出一个CSS例子:
#head_wrapper.s-ps-islite .s-p-top{
position: absolute;
bottom:40px;
width:100%;
height:181px;
}
其中大括号前是一个CSS选择器。意思为:选中 id 为 head_wrapper 且 class 为 s-ps-islite 的节点。大括号下的就是一条条样式规则,例如:position 指定了元素的布局方式为“绝对布局”,bottom 指定元素的下边距为“40像素”,width 指定了宽度为“100%占满父元素“,height 指定了指定了元素的高度。即我们将这样的样式配置写成这样的格式,然后用大括号括起来,在开头加上CSS选择器,这就代表这个样式对CSS选择器选中的元素生效。
在网页中一般会统一定义整个网页样式规则,并写入CSS文件中(后缀为css)。在HTML中,只需要 link 标签即可引入写好的CSS文件。
3、JavaScpit
JavaScipt:一种脚本语言。如果一个网页中只有 HTML 和 CSS 配合使用,那么这个网页能提供给用户的只有一种静态信息,缺乏交互性。而我们平常在网页中看到的一些交互和动画效果(下载进度条,提示框,轮播图等),通常都是JavaScipt的功劳,它实现了一种实态、动态、互交的页面功能。
JavaScipt通常也是以单独文件形式加载的,后缀为 js ,在HTML中通过 scipt 标签即可引入,例:
<scipt src="jquery-2.1.0.js"></scipt>
二、网页的结构
我们先自己写一个例子,再分析HTML的基本结构。先创建一个 txt 文件(名字自取),写入以下这串代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> This is a Demo</title>
</head>
<body>
<div id="container">
<div class="wrapper">
<h1 class="title">Hello World(这是一级标题)</h1>
<h2 class="title">Hello World(这是二级标题)</h2>
<p class="text">Hello, this is a paragraph.(这是段落)</p>
</div>
</div>
</body>
</html>
写好后将 txt 文件的后缀改为:.html 并双击打开。
这是一个最简单的HTML例子。开头用 DOCTYPE定义了文档的类型,其次是 html 标签,还有最后的结束标签表示闭合,内部是 head(网页头) 和 body(网页体) 标签,同样也有结束标签。其中 head 中定义了一些网页的配置和引用,例:
<meta charset="utf-8">
指定了网页的编码为UTF-8。
- title 标签定义了网页的标题,显示在网页的选项卡中(不显示在正文);
- body 标签内则是网页正文中的内容;
- div 标签定义了网页中的区块,其中它的 id 是 container,这是一个非常常用的属性,且 id 的内容在网页中是唯一的,我们可以通过它来获得这个区块;
- 在 id 区块下还有一个 div 标签,它的 class 为 wrapper,这也是一个非常常用的属性,通常与CSS配合使用来定义样式;
- h1 标签为:一级标题;
- h2 标签为:二级标题;
- p 标签为:段落(一个 p 标签表示一个段落);
一般网页标准形式就是如此,html 标签内嵌套 head 和 body 标签,head 内定义网页的配置和引用,body 标签内定义网页的正文。
三、节点树及节点间的关系
在HTML中,所有标签定义的内容都是节点,他们构成了HTML DOM树。那么什么是DOM?
DOM(Document Object Model) 是 W3C(万维网联盟)的标准,即文档对象模型。它定义了访问 HTML 和 XML 文档的标准(W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态的访问和更新文档内容、结构和样式)。
1、W3C DOM标准被分为3个不同的部分:
- 核心 DOM:针对任何结构化文档的标准模型;
- XML DOM:针对 XML 文档的标准模型;
- HTML DOM:针对 HTML 文档的标准模型;
根据 W3C 的 HTML DOM 标准,HTML文档中的所有内容都是节点
- 整个文档是一个文档的节点;
- 每个 HTML 元素是元素节点;
- HTML 元素内的文本时文本节点;
- 每个 HTML 属性是属性节点;
- 注释是注释节点;
2、HTML DOM 节点树
HTML DOM 将 HTML 文档视作树结构。这种结构被称为节点树,通过 HTML DOM,树中的所有节点均可通过 JavaScript 进行访问。所有 HTML 元素(节点)均可被修改,也可以创建或删除节点。
3、节点父、子和同胞
节点树中的节点彼此拥有层级关系:父(parent)、子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
- 在节点树中,顶端节点被称为根(root)
- 每个节点都有父节点、除了根(它没有父节点)
- 一个节点可拥有任意数量的子
- 同胞是拥有相同父节点的节点
下面的图片展示了节点树的一部分,以及节点之间的关系:
本段参考 W3SCHOOL,链接:https://www.w3school.com.cn/htmldom/dom_nodes.asp
四、选择器
现在我们已经知道网页是由许多节点组成的,CSS选择器会根据不同的节点设置不同的样式规则,那么如何定义节点?
以我们自己写的实例为例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> This is a Demo</title>
</head>
<body>
<div id="container">
<div class="wrapper">
<h1 class="title">Hello World(这是一级标题)</h1>
<h2 class="title">Hello World(这是二级标题)</h2>
<p class="text">Hello, this is a paragraph.(这是段落)</p>
</div>
</div>
</body>
</html>
三种常见的选择方式:
- 根据 id 进行筛选:在 div 节点中的 id 为container,那么就可以表示为 #contairner,其中 #开头表示选择 id,其后紧跟 id 的名称;
- 根据 class 进行筛选:如果我们想选择 class 为 wrapper 的节点,就可以使用 .wrapper,这里的(.)开头代表选择 class,其后紧跟 class 的名称;
- 根据标签名筛:想要选择二级标题,直接用 h2 即可;
- 另外CSS选择器还支持嵌套选择,各个选择器之间加上空格分隔便可以代表嵌套关系,例:
#container .wrapper p
代表先选择 id 为 container 的节点,然后选中其内部的 class 为 wrapper 的节点,然后再选择内部的 p 节点。
- 如果不加空格则表示并列关系,如:
div#container .wrapper p.text
代表先选择 id 为 container 的 div 节点,然后选中其内部的 class 为 wrapper 的节点,再进一步选中中内部的 class 为 text 的 p 节点。
下面附上CSS选择器的部分语法:
选择器 | 例子 | 例子描述 |
---|---|---|
.class | .intro | 选择 class=“intro” 的所有节点 |
#id | #firstname | 选择 id=“firstname”的所有节点 |
* | * | 选择所有节点 |
element | p | 选择所有 p 节点 |
element , element | div , p | 选择所有 div 节点和所有 p 节点 |
element element | div p | 选择 div 节点内的所有 p 节点 |
element>element | div>p | 选择父节点为 div 节点的所有 p 节点 |
element+element | div+p | 选择紧接在 div 节点之后的所有 p 节点 |
[ attribute ] | [ target ] | 选择带有 target 属性的所有节点 |
[ attribute=value ] | [ target=blank ] | 选择带有 target=“blank” 的所有节点 |
[ attrubute~=value ] | [ title~=flower ] | 选择 title 属性包含单词 flower 的所有节点 |
: link | a : link | 选择所有未被访问的链接 |
: visited | a : visited | 选择所有已被访问的链接 |
: active | a : active | 选择活动链接 |
: hover | a : hover | 选择鼠标指针位于其上的链接 |
: focus | input : focus | 选择获得焦点的 input 节点 |
: first-letter | p : first-letter | 选择每个 p 节点的首字母 |
: first-line | p : first-line | 选择每个 p 节点的首行 |
: first-child | p : first-child | 选择属于父节点的第一个子节点的所有 p 节点 |
: before | p : before | 在每个 p 节点的内容之前插入内容 |
: after | p : after | 在每个 p 节点的内容之后插入内容 |
: lang(language) | p : lang | 选择带有 it 开头的 lang 属性值的所有 p 节点 |
element1~element2 | p~ul | 选择前面有 p 节点的所有 ul 节点 |
[ attribute^=value ] | a[ src^=“https” ] | 选择其 src 属性值以 https 开头的所有 a 节点 |
[ attribute$=value ] | a[ src$=“.pdf” ] | 选择其 src 属性以 .pdf 结尾的所有 a 节点 |
[ attribute*=value ] | a[ src8=“abc” ] | 选择其 src 属性中包含 abc 字串的所有 a 节点 |
: first-of-type | p : first-of-type | 选择属于其父节点的首个 p 节点的所有 p 节点 |
: last-of-type | p : last-of-type | 选择属于其父节点的最后 p 节点的所有 p 节点 |
: only-of-type | p : only-of-type | 选择属于其父节点唯一的 p 节点的所有 p 节点 |
: only-child | p : only-child | 选择属于其父节点的唯一子节点的所有 p 节点 |
: nth-child(n) | p : nth-child | 选择属于其父节点的第二个子节点的所有 p 节点 |
: nth-last-child(n) | p : nth-last-child | 同上,从最后一个子节点开始计数 |
: nth-of-type(n) | p : nth-of-type | 选择属于其父节点第二个 p 节点的所有 p 节点 |
: nth-last-of-type | p : nth-last-of-type | 同上,但是从最后一个子节点开始计数 |
: last-child | p : last-child | 选择属于其父节点最后一个子节点的所有 p 节点 |
: root | : root | 选择文档的根节点 |
: empty | p : empty | 选择没有子节点的所有 p 节点(包括文本节点) |
: target | #new : target | 选择当前活动的 #new 节点 |
: enabled | input : enabled | 选择每个启用的 input 节点 |
: disabled | input : disabled | 选择每个禁用的 input 节点 |
: checked | input : checked | 选择每个被选中的 input 节点 |
: not(selector) | : not | 选择非 p 节点的所有节点 |
: : selection | : : selection | 选择被用户选取的节点部分 |
所有内容全部引自《python3 网络爬虫开发实战(人民邮电出版社)》,此笔记仅用于学习。