理解HTML和XPath ######################################## 为了从网页提取信息,了解网页的结构是非常必要的。我们会快速学习HTML、HTML的树结构和用来筛选网页信息的XPath。 HTML、DOM树结构和XPath **************************************** 从这本书的角度,键入网址到看见网页的整个过程可以分成四步: #. 在浏览器中输入网址URL。URL的第一部分,也即域名(例如gumtree.com),用来搜寻网络上的服务器。URL和其他像cookies等数据形成了一个发送到服务器的请求request。 #. 服务器向浏览器发送HTML。服务器也可能发送XML或JSON等其他格式,目前我们只关注HTML。 #. HTML在浏览器内部转化成树结构:文档对象模型(DOM)。 #. 根据布局规范,树结构转化成屏幕上的真实页面。 .. image:: assets/22-41-02.png 研究下这四个步骤和树结构,可以帮助定位要抓取的文本和编写爬虫。 URL URL包括两部分:第一部分通过DNS定位服务器,例如当你在浏览器输入https://mail.google.com/mail/u/0/#inbox这个地址时,产生了一个mail.google.com的DNS请求,后者为你解析了一台服务器的IP地址,例如173.194.71.83。也就是说,https://mail.google.com/mail/u/0/#inbox转换成了https://173.194.71.83/mail/u/0/#inbox。 URL其余的部分告诉服务器这个请求具体是关于什么的,可能是一张图片、一份文档或是触发一个动作,例如在服务器上发送一封邮件。 HTML文档 **************************************** 服务器读取URL,了解用户请求,然后回复一个HTML文档。HTML本质是一个文本文件,可以用TextMate、Notepad、vi或Emacs等软件打开。与大多数文本文件不同,HTML严格遵循万维网联盟(World Wide Web Consortium)的规定格式。这个格式超出了本书的范畴,这里只看一个简单的HTML页面。如果你打开http://example.com,点击查看源代码,就可以看到HTML代码,如下所示: .. code-block:: html
This domain is established to be used for illustrative examples examples in documents. You may use this domain in examples without prior coordination or asking for permission.
标签分隔段落,浏览器对这种行为是容许的,会智能判断哪里该有结束标签
。与
之间的内容称作HTML的元素。元素之间可以嵌套元素,比如例子中的标签,后者包含了一个标签。
有些标签稍显复杂,例如,带有URL的href部分称作属性。
最后,许多标签元素包含有文本,例如 ,出现在浏览器和DOM中:
.. image:: assets/22-43-25.png
用XPath选择HTML元素
如果你以前接触过传统的软件工程,并不知道XPath,你可能会担心,在HTML文档中查询某个信息,要进行复杂的字符串匹配、搜索标签、处理特殊字符、解析整个树结构等繁琐工作。对于XPath,所有的这些都不是问题,你可以轻松提取元素、属性或是文字。
在Chrome中使用XPath,在开发者工具中点击控制台标签,使用$x功能。例如,在网页http://example.com/的控制台,输入$x('//h1'),就可以移动到 ... ... ... ... 标签在 ... ... This domain ... permission.标签中的Example Domain。对我们而言,标签之间的可见内容更为重要。头部标签中指明了编码字符,由Scrapy对其处理,就不用我们浪费精力了。
树结构
****************************************
不同的浏览器有不同的借以呈现网页的内部数据结构。但DOM树是跨平台且不依赖语言的,可以被几乎所有浏览器支持。
只需右键点击,选择查看元素,就可以在浏览器中查看网页的树结构。如果这项功能被禁止了,可以在选项的开发者工具中修改。
你看到的树结构和HTML很像,但不完全相同。无论原始HTML文件使用了多少空格和换行符,树结构看起来都会是一样的。你可以点击任意元素,或是改变属性,这样可以实时看到对HTML网页产生了什么变化。例如,如果你双击了一段文字,并修改了它,然后点击回车,屏幕上这段文字就会根据新的设置发生改变。在右边的方框中,在属性标签下面,你可以看到这个树结构的属性列表。在页面底部,你可以看到一个面包屑路径,指示着选中元素的所在位置。
.. image:: assets/22-42-54.png
重要的是记住,HTML是文本,而树结构是浏览器内存中的一个对象,你可以通过程序查看、操作这个对象。在Chrome浏览器中,就是通过开发者工具查看。
浏览器中的页面
****************************************
HTML文本和树结构和我们平时在浏览器中看到的页面截然不同。这恰恰是HTML的成功之处。HTML文件就是要具有可读性,可以区分网页的内容,但不是按照呈现在屏幕上的方式。这意味着,呈现HTML文档、进行美化都是浏览器的职责,无论是对于功能齐备的Chrome、移动端浏览器、还是Lynx这样的文本浏览器。
也就是说,网页的发展对网页开发者和用户都提出了极大的开发网页方面的需求。CSS就是这样被发明出来,用以服务HTML元素。对于Scrapy,我们不涉及CSS。
既然如此,树结构对呈现出来的网页有什么作用呢?答案就是盒模型。正如DOM树可以包含其它元素或是文字,同样的,盒模型里面也可以内嵌其它内容。所以,我们在屏幕上看到的网页是原始HTML的二维呈现。树结构是其中的一维,但它是隐藏的。例如,在下图中,我们看到三个DOM元素,一个
和
元素,如截图所示:
.. image:: assets/22-43-58.png
你在控制台中看到的是一个包含所选元素的JavaScript数组。如果你将光标移动到这个数组上,你可以看到被选择的元素被高亮显示。这个功能很有用。
XPath表达式
HTML文档的层级结构的最高级是标签,你可以使用元素名和斜杠线选择任意元素。例如,下面的表达式返回了http://example.com/上对应的内容:
.. code-block:: none
$x('/html')
[ ... ]
$x('/html/body')
[ ... ]
$x('/html/body/div')
[
Example Domain
]
$x('/html/body/div/p')
[ Example Domain
']
response.xpath('/html/body/div/p').extract()
[u'