信息展示在网页上。图 14-1 展示了一个简单的网页(网址为 data/simple-page.html),
包括标题和一个段落:
所有现代浏览器都支持这样的网页。用任意的文本编辑器打开 data/simple-page.html,
就会看到网页背后的代码,如下所示:
<!DOCTYPE html>
<html>
<head>
<title>Simple page</title>
</head>
<body>
<h1>Heading 1</h1>
<p>This is a paragraph.</p>
</body>
</html>
上述代码是 HTML(Hyper Text Markup Language)的一个例子。HTML 是互联网中使
用最广泛的语言。与其他任何一种语言都不同的是:HTML 描述了网页的布局排版和内容,
浏览器则根据 Web 标准将代码渲染到网页上(而其他语言最终都被转换为计算机指令)。
现代 Web 浏览器根据 HTML 的第一行决定使用哪种标准进行网页渲染。在上面的例子
中,使用的是最新标准 HTML 5。
通篇阅读代码,就会发现 HTML 是一些标签的嵌套结构,这些标签包括:<html>、
<title>、<body>、<h1> 和 <p>。每一个标签都是以<tag>开始,以</tag>结束。
事实上,网页的这些标签并不是随意命名的,也不能任意包含其他标签。每个标签对
浏览器都有特殊含义,且只允许包含一部分特定的标签,或不允许包含任何标签。
标签 <html> 是所有 HTML 的根元素。HTML 通常也包括 <head> 和 <body>。其中,
标签 <head> 通常包含 <title>,展示在标题栏上,包括浏览标签和网页元数据。
而 <body> 则在网页内容和排版方面起主要作用。
在 <body> 标签中,标签可以更自由地嵌套。最简单的一个网页可以只包含一级标题
(<h1>)和一个段落(<p>)。这个网页(图 14-2)包含一个 2 行 2 列的表格。
图 14-1
图 14-2
网页背后的 HTML 代码存储在 data/single-table.html 中:
<!DOCTYPE html>
<html>
<head>
<title>Single table</title>
</head>
<body>
<p>The following is a table</p>
<table id = "table1" border = "1">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jenny</td>
<td>18</td>
</tr>
<tr>
<td>James</td>
<td>19</td>
</tr>
</tbody>
</table>
</body>
</html>
注意到,标签<table>是按行构建的:<tr> 指表格的行,<th> 指表头单元格,
<td> 指表格的单元格。
同时,HTML 元素,例如<table>,采
用<table attr1 = "value1" attr2 =
"value2"> 格式时,<table> 可能就会具有
其他的属性。这些属性并不是随意定义的。相
反,根据相应的标准,每一个属性都有特定含
义。在前面的代码中,id 是表格的标识符,
border 用于控制边框宽度。
下面这个页面(见图 14-3)的内容样式看
起来和前面的有所不同:
图 14-3
如果查看 data/simple-products.html 的源代码,就会发现一些新的标签,例如 <div>(章
节)、<ul>(无序列表)、<li>(列表项目)和 <span>(应用样式的章节);此外,许
多 HTML 元素还有一个属性,称为 style,用于定义这些元素的样式外观:
<!DOCTYPE html>
<html>
<head>
<title>Products</title>
</head>
<body>
<h1 style = "color: blue;">Products</h1>
<p>The following lists some products</p>
<div id = "table1" style = "width: 50px;">
<ul>
<li>
<span style = "font-weight: bold;">Product-A</span>
<span style = "color: green;">$199.95</span>
</li>
<li>
<span style = "font-weight: bold;">Product-B</span>
<span style = "color: green;">$129.95</span>
</li>
<li>
<span style = "font-weight: bold;">Product-C</span>
<span style = "color: green;">$99.95</span>
</li>
</ul>
</div>
</body>
</html>
style 中的值以这样的方式编写:property1: value1; property2: value2;。但是,
列表项目的样式有点繁琐,因为所有的产品名称都共享同一个样式,产品价格亦是如此。下面这
个 HTML(data/products.html)使用 CSS(Cascading Style Sheets)来避免冗长的样式定义:
<!DOCTYPE html>
<html>
<head>
<title>Products</title>
<style>
h1 {
color: darkblue;
}
.product-list {
width: 50px;
}
.product-list li.selected .name {
color: 1px blue solid;
}
.product-list .name {
font-weight: bold;
}
.product-list .price {
color: green;
}
</style>
</head>
<body>
<h1>Products</h1>
<p>The following lists some products</p>
<div id = "table1" class = "product-list">
<ul>
<li>
<span class = "name">Product-A</span>
<span class = "price">$199.95</span>
</li>
<li class = "selected">
<span class = "name">Product-B</span>
<span class = "price">$129.95</span>
</li>
<li>
<span class = "name">Product-C</span>
<span class = "price">$99.95</span>
</li>
</ul>
</div>
</body>
</html>
注意到,我们在<head>中添加了<style>来声明网页的全局样式表。也将 style 转
换为 class,以便内容元素(div、li 和 span)使用这些预定义的样式。我们借助下述
代码简要介绍一下 CSS 的语法。
匹配所有<h1> 元素:
h1 {
color: darkblue;
}
匹配所有属于 product-list 类的元素:
.product-list {
width: 50px;
}
先匹配所有属于 product-list 类的元素,再从中匹配所有属于 name 类的嵌套元素:
.product-list .name {
font-weight: bold;
}
先匹配所有属于 product-list 类的元素,再从中匹配所有属于 selected 类的嵌
套 <li> 元素,最后从这些嵌套元素中匹配属于 name 类的:
.product-list li.selected .name {
color: 1px blue solid;
}
要提醒的是,单纯使用 style 不能实现
上述目标。图 14-4 展示了网页的渲染效果。
每个 CSS 元素都包含一个 CSS 选择器
(例如 .product-list)用来匹配 HTML 元素
和样式(例如 color:red)以便渲染应用。
CSS 选择器不仅用于应用样式,也常用于提取
网页内容,以便我们感兴趣的 HTML 元素可以
被正确地匹配,这是网络爬虫背后的底层技术。
CSS 的内容比上述代码展示出来的要丰
富得多。对于网络爬虫,我们使用下面这些例
子展示最常用的 CSS 选择器,如表 14-1 所示。
表 14-1
语法 匹配
* All elements
h1, h2, h3 <h1>,<h2>,<h3>
#table <* id="table1">
图 14-4
续表
语法 匹配
.product-list <* class="product-list">
div#container <div id="container">
div a <div> <a>and<div> <p> <a>
div > a <div> <a>but not<div> <p> <a>
div > a.new <div> <a class="new">
ul > li:first-child First <li> in <ul>
ul > li:last-child Last <li> in<ul>
ul > li:nth-child(3) 3rd <li> in <ul>
p + * Next element of <p>
img[title] <img>with title attribute
table[border=1] <table border="1">
每个级别上,tag#id.class[ ] 可以和可选项:tag、#id.class 和 [ ] 一起使用。
更多关于 CSS 选择器的信息,请访问 https://developer.mozilla.org/en-US/docs/Web/CSS/
CSS_Selectors。想了解更多关于 HTML 的标签,可以访问 http://www.w3schools.com/tags/。