一旦你开始采集网络数据,就会感受到浏览器为我们做的所有细节。网络上如果没有HTML 文本格式层、CSS 样式层、JavaScript 执行层和图像渲染层,乍看起来会有点儿吓人,但是在这一章和下一章,我们将介绍如何不通过浏览器的帮助来格式化和理解数据。 本章将首先向网络服务器发送GET 请求以获取具体网页,再从网页中读取HTML 内容, 最后做一些简单的信息提取,将我们要寻找的内容分离出来。 1.1 网络连接 如果你没在网络或网络安全上花过太多时间,那么互联网的原理可能看起来有点儿神秘。准确地说,每当打开浏览器连接http://google.com 的时候,我们不会思考网络正在做什么, 而且如今也不必思考。实际上,我认为很神奇的是,计算机接口已经如此先进,让大多数人上网的时候完全不思考网络是如何工作的。 但是,网络数据采集需要抛开一些接口的遮挡,不仅是在浏览器层(它如何解释所有的HTML、CSS 和JavaScript),有时也包括网络连接层。 我们通过下面的例子让你对浏览器获取信息的过程有一个基本的认识。Alice 有一台网络服务器。Bob 有一个台式机正准备连接Alice 的服务器。当一台机器想与另一台机器对话时,下面的某个行为将会发生。 1. Bob 的电脑发送一串1 和0 比特值,表示电路上的高低电压。这些比特构成了一种信息,包括请求头和消息体。请求头包含当前Bob 的本地路由器MAC 地址和Alice 的IP地址。消息体包含Bob 对Alice 服务器应用的请求。 2. Bob 的本地路由器收到所有1 和0 比特值,把它们理解成一个数据包(packet),从Bob 自己的MAC 地址“寄到”Alice 的IP 地址。他的路由器把数据包“盖上”自己的IP 地址作为“发件”地址,然后通过互联网发出去。 3. Bob 的数据包游历了一些中介服务器,沿着正确的物理/ 电路路径前进,到了Alice 的服务器。 4. Alice 的服务器在她的IP 地址收到了数据包。 5. Alice 的服务器读取数据包请求头里的目标端口(通常是网络应用的80 端口,可以理解成数据包的“房间号”,IP 地址就是“街道地址”),然后把它传递到对应的应用——网络服务器应用上。 6. 网络服务器应用从服务器处理器收到一串数据,数据是这样的: ♦ 这是一个GET 请求 ♦ 请求文件index.html 7. 网络服务器应用找到对应的HTML 文件,把它打包成一个新的数据包发送给Bob,然后通过它的本地路由器发出去,用同样的过程回传到Bob 的机器上。 瞧!我们就这样实现了互联网。 那么,在这场数据交换中,网络浏览器从哪里开始参与的?完全没有参与。其实,在互联网的历史中,浏览器是一个比较年轻的发明,始于1990 年的Nexus 浏览器。 的确,网络浏览器是一个非常有用的应用,它创建信息的数据包,发送它们,然后把你获取的数据解释成漂亮的图像、声音、视频和文字。但是,网络浏览器就是代码,而代码是可以分解的,可以分解成许多基本组件,可重写、重用,以及做成我们想要的任何东西。网络浏览器可以让服务器发送一些数据,到那些对接无线(或有线)网络接口的应用上, 但是许多语言也都有实现这些功能的库文件。 让我们看看Python 是如何实现的: from urllib.request import urlopen html = urlopen("http://pythonscraping.com/pages/page1.html") print(html.read()) 你可以把这段代码保存为scrapetest.py,然后在终端里运行如下命令: $python scrapetest.py 注意,如果你的设备上安装了Python 2.x,可能需要直接指明版本才能运行Python 3.x 代码: $python3 scrapetest.py 这将会输出http://pythonscraping.com/pages/page1.html 这个网页的全部HTML 代码。更准确地说,这会输出在域名为http://pythonscraping.com 的服务器上< 网络应用根地址>/ pages 文件夹里的HTML 文件page1.html 的源代码。 有什么区别?现在大多数网页需要加载许多相关的资源文件。可能是图像文件、JavaScript 文件、CSS 文件,或你需要连接的其他各种网页内容。当网络浏览器遇到一个标签时,比如<img src="cuteKitten.jpg">,会向服务器发起另一个请求,以获取cuteKitten.jpg 文件中的数据为用户充分渲染网页。但是,我们的Python 程序没有返回并向服务器请求多个文件的逻辑,它只能读取我们已经请求的单个HTML 文件。 那么我们应该怎样做呢?幸好Python 语法接近正常英文,下面这行代码 from urllib.request import urlopen 其实已经显示了它的含义:它查找Python 的request 模块(在urllib 库里面),只导入一个urlopen 函数。 urllib 还是urllib2 ? 如果你用过Python 2.x 里的urllib2 库,可能会发现urllib2 与urllib 有些不同。在Python 3.x 里,urllib2 改名为urllib,被分成一些子模块:urllib.request、urllib.parse 和urllib.error。尽管函数名称大多和原来一样,但是在用新的urllib 库时需要注意哪些函数被移动到子模块里了。 urllib 是Python 的标准库(就是说你不用额外安装就可以运行这个例子),包含了从网络请求数据,处理cookie,甚至改变像请求头和用户代理这些元数据的函数。我们将在本书中广泛使用urllib,所以建议你读读这个库的Python 文档(https://docs.python.org/3/ library/urllib.html)。 urlopen 用来打开并读取一个从网络获取的远程对象。因为它是一个非常通用的库(它可以轻松读取HTML 文件、图像文件,或其他任何文件流),所以我们将在本书中频繁地使用它。
Python网络数据采集——1.1 网络连接
书名: Python网络数据采集
作者: [美] 米切尔
出版社: 人民邮电出版社
译者: 陶俊杰 | 陈小莉
出版年: 2016-3-1
页数: 200
定价: CNY 59.00
装帧: 平装
ISBN: 9787115416292