注:本文来自于书籍:《Python网络爬虫开发实战》 崔庆才著 第二章,书籍分享链接在文章末尾
本章介绍爬虫之前需要学习的基础知识,如HTTP原理、网页的基础知识、爬虫的基本原理、Cookies的基本原理等。
URL是 URI的子集,也就是说每个URL 都是URI,但不是每个URI都是 URL。
那么,怎样的URI不是URL 呢?
URI还包括一个子类叫作URN,它的全称为Universal Resource Name,即统一资源名称。URN只命名资源而不指定如何定位资源,比如 urn:isbn:0451450523指定了一本书的ISBN,可以唯一标识这本书,但是没有指定到哪里定位这本书,这就是URN。URL、URN和URI的关系可以用图2-1表示。
URL、URN和URI关系图
超文本,其英文名称叫作 hypertext,我们在浏览器里看到的网页就是超文本解析而成的,其网页源代码是一系列HTML代码,里面包含了一系列标签,比如 img 显示图片,p指定显示段落等。浏览器解析这些标签后,便形成了我们平常看到的网页,而网页的源代码。
我们在浏览器中输入一个URL,回车之后便会在浏览器中观察到页面内容。实际上,这个过程是浏览器向网站所在的服务器发送了一个请求,网站服务器接收到这个请求后进行处理和解析,然后返回对应的响应,接着传回给浏览器。响应里包含了页面的源代码等内容,浏览器再对其进行解析,便将网页呈现了出来,模型如图所示。
请求,由客户端向服务端发出,可以分为4部分内容:请求方法(Request Method )、请求的网址(Request URL)、请求头( Request Headers)、请求体(Request Body ).
常见的请求方法:GET和POST
GET和 POST请求方法有如下区别。
即统一资源定位符URL,唯一确定我们想请求的资源
请求头,用来说明服务器要使用的附加信息,比较重要的信息有Cookie 、Referer、User-Agent 等。
请求体一般承载的内容是POST请求中的表单数据,而对于GET请求,请求体则为空。
在爬虫中,如果要构造POST 请求,需要使用正确的Content-Type,并了解各种请求库的各个参数设置时使用的是哪种Content-Type,不然可能会导致 POST提交后无法正常响应。
响应,由服务端返回给客户端,可以分为三部分:响应状态码(Response Status Code)、响应头( Response Headers )和响应体(Response Body ).
响应状态码表示服务器的响应状态,如200代表服务器正常响应,404代表页面未找到,500代表服务器内部发生错误。在爬虫中,我们可以根据状态码来判断服务器响应状态。
响应头包含了服务器对请求的应答信息,如Content-Type、Server 、Set-Cookie等。下面简要说明—些常用的头信息。
响应的正文数据,比如请求网页时,它的响应体就是网页的HTML代码,请求一张图片时,它的响应体就是图片的二进制数据。
做爬虫请求网页后,要解析的内容就是响应体。
在做爬虫时,我们主要通过响应体得到网页的源代码、JSON数据等,然后从中做相应内容的提取。
网页可以分为三大部分——**HTML、CSS和JavaScript。**如果把网页比作一个人的话,HTML相当于骨架,JavaScript相当于肌肉,CSS相当于皮肤,三者结合起来才能形成一个完善的网页。
HTML是用来描述网页的一种语言,其全称叫作Hyper Text Markup Language,即超文本标记语言。网页包括文字、按钮、图片和视频等各种复杂的元素,其基础架构就是HTML。不同类型的文字通过不同类型的标签来表示。如图片用img标签表示
CSS,全称叫作 Cascading Style Sheets,即层叠样式表。“层叠”是指当在HTML中引用了数个样式文件,并且样式发生冲突时,浏览器能依据层叠顺序处理。“样式”指网页中文字大小、颜色、元素间距、排列等格式。例如:
#head_wrapper.s-ps-islite .s-p-top {
position: absolute;
bottom: 40px;
width: 100%;
height: 181px;
}
JavaScript,简称JS,是一种脚本语言。HTML和 CSS配合使用,提供给用户的只是一种静态信息,缺乏交互性。我们在网页里可能会看到一些交互和动画效果,如下载进度条、提示框、轮播图等,这通常就是JavaScript 的功劳。它的出现使得用户与信息之问不只是一种浏览与显示的关系,而是实现了一种实时、动态、交互的页面功能。
JavaScript 通常也是以单独的文件形式加载的,后缀为 js ,在 HTML 中通过 script 标签即可引入。
例如:
<script src: "j query-2 .1. o. j s" ></script>
一个网页的标准形式是html标签内嵌套head和 body标签,head内定义网页的配置和引用. body内定义网页的正文。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"> //指定网页编码
<title>This is a Demo</title> //网页标题
</head>
<body> //正文部分
<div id=”container”> //网页中的区块
<div class ="wrapper”〉
<h2 class =”title”>Hello World</h2> //h2表示二级标题
<p class =” text ”> Hello, this is a paragraph.</p> //p表示一个段落
</div>
</div>
</body>
</html>
在HTML中,所有标签定义的内容都是节点,它们构成了一个HTML DOM树。
我们先看下什么是 DOM。
w3C DOM标准被分为3个不同的部分。
根据W3C的HTML DOM标准,HTML文档中的所有内容都是节点。
HTML DOM将HTML文档视作树结构,这种结构被称为节点树。
通过HTML DOM,树中所有节点均可通过JavaScript访问,所有 HTML 节点元素均可被修改,创建或删除。
本段参考W3SCHOOL,链接:link
如何定位节点?
例如,上例中div节点的id为container,那么就可以表示为北container,其中#开头代表选择id,其后紧跟id的名称。另外,如果我们想选择class为wrapper的节点,便可以使用.wrapper。
此外,CSS选择器还支持嵌套选择,各个选择器之间加上空格分隔开便可以代表嵌套关系。例如:
- #container .wrapper p则代表先选择id为container的节点,然后选中其内部的class为 wrapper的节点,然后再进一步选中其内部的p节点。
- 另外,如果不加空格,则代表并列关系,如divtcontainer .wrapperp.text 代表先选择id为container的div节点.
- 然后选中其内部的class为 wrapper的节点,再讲一步选中其内部的class为text的p 节点。
这就是CSS选择器,其筛选功能还是非常强大的。
爬虫首先要做的动作就是获取网页,即获取网页的源代码。Python提供了许多库来帮助我们实现请求-响应的操作,如urllib、requests等。我们可以用这些库来帮助我们实现HTTP请求操作,请求和响应都可以用类库提供的数据结构来表示,得到响应之后只需要解析数据结构中的 Body部分即可,即得到网页的源代码,这样我们可以用程序来实现获取。
获取网页源代码后,接下来就是分析网页源代码,从中提取我们想要的数据。
提取信息后,我们一般会将提取到的数据保存到某处以便后续使用。这里保存形式有多种多样,如可以简单保存为TXT文本或JSON文本,也可以保存到数据库,如 MySQL和 MongoDB等。
爬虫就是代替我们完成爬取工作的自动化程序,它可用在抓取过程中农进行各种异常处理、错误重试等操作,确保爬虫持续高效地进行。
有时候,我们在用urllib或requests抓取网页时,得到的源代码实际和浏览器中看到的不一样。
这是因为网页可能是由JavaScript渲染出来的,也就是说原始的HTML代码是一个空壳。
< ! OOCTYPE html>
<html>
<head>
<meta charset="UTF-8” >
<title>This is a Oemo</title>
</head>
<body>
<div id=”container” >
</div>
</body>
<script src=” app.js”></script> //负责网页的渲染
</html>
获取app.js文件后,会执行其中的JavaSript代码,而JavaScript则会改变HTML中的节点,向其添加内容,最后得到完整的页面。
但是在用urllib或requests等库请求当前页面时,我们得到的只是这个HTML代码,它不会帮助我们去继续加载这个JavaScript文件,这样也就看不到浏览器中的内容了。
因此,使用基本HTTP请求库得到的源代码可能跟浏览器中的页面源代码不太一样。对于这样的情况,我们可以分析其后台Ajax接口。也可使用Selenium、Splash这样的库来实现模拟JJavaScript渲染。
有些网站需要登录之后才可以访问,而且登录之后可以连续访问很多次网站,但是有时候过一段时间就需要重新登录。还有一些网站,在打开浏览器时就自动登录了,而且很长时间都不会失效,这是为什么?
动态网页不再是一个简单的HTML,可能是由JSP、PHP、Python等语言编写的。它可以实现用户登录和注册的功能
HTTP的无状态是指HTTP协议对事务处理是没有记忆能力的,也就是说服务器不知道客户端是什么状态。当我们向服务器发送请求后,服务器解析此请求,然后返回对应的响应,服务器负责完成这个过程,而且这个过程是完全独立的,服务器不会记录前后状态的变化,也就是缺少状态记录。
为了保证前后状态,出现了两个用于保持HTTP连接状态的技术,它们分别是会话和Cookies。
会话,而在Web中,会话对象用来存储特定用户会话所需的属性及配置信息。
这样,当用户在应用程序的Web页之间跳转时,存储在会话对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的Web页时,如果该用户还没有会话,则Web服务器将自动创建一个会话对象。当会话过期或被放弃后,服务器将终止该会话。
Cookies指某些网站为了辨别用户身份,进行会话跟踪而存储在用户本地终端上的数据。
Cookies和会话需要配合,一个处于客户端,一个处于服务端,二者共同协作,就实现了登录会话控制。
在浏览器开发者工具中打开Application选项卡,左侧会有一个Storage部分,最后一项为Cookies
从表面意思来说,会话Cookie就是把Cookie放在浏览器内存里,浏览器在关闭之后该Cookie即失效;持久Cookie则会保存到客户端的硬盘中,下次还可以继续使用,用于长久保持用户登录状态。
“只要关闭浏览器,会话就消失了?”。
不是的。当我们关闭浏览器时,浏览器不会主动在关闭之前通知服务器它将要关闭,所以服务器根本不会有机会知道浏览器已经关闭。
而且恰恰是由于关闭浏览器不会导致会话被删除,这就需要服务器为会话设置一个失效时间,当距离客户端上一次使用会话的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把会话删除以节省存储空间。
爬虫的时候有时候会出现:“您的IP访问频率太高”这样的提示,这是因为网站采取了一些反爬虫措施。比如,服务器会检测某个P在单位时间内的请求次数,如果超过了这个阈值,就会直接拒绝服务,返回一些错误信息,这种情况可以称为封IP。
那怎么办?
借助某种方式来伪装我们的IP,让服务器识别不出是由我们本机发起的请求,就可以!一种有效的方式是使用代理
代理实际上指的就是代理服务器,英文叫作proxy server,它的功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中转站。在我们正常请求一个网站时,是发送了请求给Web服务器,Web服务器再把响应传回给我们,如果设置了代理服务器,就是这样的:
这个我们依然可以正常访问网页,但是Web服务器识别的真实IP不是我们本机的IP了,这就实现了IP伪装。
使用代理隐藏真实的IP,让服务器误以为是代理服务器在请求自己。这样在爬取过程中通过不断更换代理,就不会被封锁,可以达到很好的爬取效果。
忘记放链接啦!!在这里,需要的朋友自取:
《Python3网络爬虫开发实战》崔庆才著 链接:《Python3网络爬虫开发实战》崔庆才著
链接:https://pan.baidu.com/s/18W1LoneXa-L31N9KADDF7w
提取码:8888