Python3网络爬虫开发实践笔记: 1.爬虫基础

摘要

爬虫的目标对象是网络资源,其中最重要的部分是网页,本章主要涉及 HTTP原理、网页基础知识、爬虫基本原理、Cookies基本原理等内容。

1.1 HTTP基本原理

在浏览器输入URL到获取网页的过程中,HTTP协议有重要作用,保证超文本传输的高效和准确

1.1.1 URL和URI

互联网上有各种各样的资源,为了区分这些资源,URI(Uniform Resource Identifier)统一资源标识符诞生了,URI又分为URL(Universal Resource Locator)统一资源定位符和URN(Universal Resource Name)统一资源名称,他们都可以唯一对应一个资源,但是通过URL标明了资源的位置,可以获取到对应的资源。而URN只是唯一确认了一个资源,并不能用来获取对应资源。

1.1.2 超文本

超文本(Hypertext)可以看成网页的源代码,经过浏览器解析之后生成的就是平时看到的网页,比如HTML代码。

1.1.3 HTTP & HTTPS

HTTP全称Hyper Text Transfer Protocol即超文本传输协议,HTTPS全称Hyper Text Transfer Protocol Over Secure Socket Layer,加入了SLL层来加密传输内容,主要有两个功能:1.加密内容 2.由CA机构颁发安全证书,方便用户查看。

1.1.4 HTTP请求过程

可以通过浏览器的检查功能来查看HTTP请求的信息,对于一个HTTP请求来说,通常包括求网址: 请求方法、状态代码、远程地址、引荐来源网址政策、请求头、响应头等信息。具体内容将在接下来的请求和响应部分解释。

1.1.5 请求

请求由客户端发出、服务器接收,主要包括四部分内容:请求类型、请求网址、请求头、请求体。

  1. 请求类型:
    常见的请求类型主要分为:GET和POST。
    在浏览器中输入URL之后,会发起GET请求,请求的参数直接反映在URL中;而登录时输入的密码,则会以填写表单的形式传输,发起POST请求,参数不会反映在URL中。
    POST和GET的不同之处主要有两个:

    • GET类型的参数包含在URL中,POST类型的参数通过表单传输,不包含在URL中。
    • GET类型提交的数据最多1024字节,而POST类型没有限制

    其他的请求方法还有:HEAD、PUT、DELETE、CONNECT、OPTIONS、TRACE等。

  2. 请求网址:
    即URL

  3. 请求头:
    请求头包含了服务器处理请求所需的主要信息,按功能可以分为以下几种:

    1. 对客户端可接收响应的定义:accept、accept-encoding、accept-language
    2. 对客户端信息的定义:user-agent、cookies
    3. 对发起请求来源的定义: refer
    4. 对服务端的定义:host
    5. 对请求体的定义:content-type、content_length
  4. 请求体:
    负责包含POST请求提交的参数,而GET请求的请求体时空的。

1.1.6 响应

响应主要分为响应状态码、响应头、响应体三部分

  1. 响应状态码:
    用不同的数字表示不同的响应状态,200表示正常,404表示页面未找到、500表示服务器内部错误等等
  2. 响应头:
    响应头包含了客户端浏览器处理响应所需要的信息,按功能可分为以下几类:
    1. 对响应内容的定义:content-encoding、content-type、content-security-policy
    2. 对服务器的定义: server、data、last-modified
    3. 对浏览器的设置: set-cookie
  3. 响应体:
    对应的目标内容,网页对应HTML代码,图片对应二进制串,是爬虫中需要解析的部分。

1.2 网页基础

1.2.1 网页组成

网页主要由三部分组成:HTML、CSS、Javascript,HTML提供网页各种元素的框架,CSS负责组织各种元素的显示,美化网页,Javascript则负责提供网页的交互功能。

1.2.2 网页结构

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>
        This is a Test
    </title>

<body>
    <div id="container">
        <div class="wrapper">
            <h2 class="title">Hello World!</h2>
            <p class="text">Welcome to this page.</p>
        </div>
    </div>
</body>
</head>

</html>

以上是一个简单的HTML代码,可以看出各种元素是层层嵌套,形成一颗以HTML文件为根节点的树型结构。

1.2.3 节点树和节点的关系

DOM树:Document Object Model,定义了访问HTML和XML文档的标准。文档中的每个元素、属性、文本都构成一个节点,而节点之间根据HTML语法自然形成父子、兄弟节点的关系。其中每个节点都可以通过Javascript来访问。

1.2.4 选择器

CSS在位不同节点设置不同样式的时候,需要能够识别特定的元素,这时CSS使用的是CSS选择器。CSS选择器的常用方法主要包括以下几种:

  1. {#}id 对特定的id选择
  2. 。class 对class选择
  3. {*} 全部元素
  4. element 选择全部element节点
  5. 等等

此外还支持嵌套的选择 比如 head #title 是对head节点里id=title的节点的选择。

1.3 爬虫原理

1.3.1 爬虫过程

爬虫的过程可以简单分为:获取网页->提取数据->存储数据:

  1. 获取网页可以使用Urllib、Requests等python库,模拟请求,并获取URL对应的资源。
  2. 而获取到资源后,还需要使用提取工具,例如正则表达式、CSS选择器、Xpath选择器来提取有用的数据。
  3. 提取到数据之后,要做的是存储和管理数据,可以简单的存为对应的txt或json文件,但是更好的做法是使用数据库,例如Mysql、MongoDB等数据库。也可以传输到远程服务器存储。

1.3.2 能爬取的数据

可以通过URL访问的资源都可以被存储,最常见的是HTML文件,还有API接口常用的JSON数据,还有各种的文件,比如图片、CSS、js等文件。

1.3.3 Javascript渲染

现在越来越多的网站采用JavaScript来渲染页面,导致看到的html代码和对应的页面不一致,看到的页面是通过执行html文件里的js文件对应的代码渲染出来的。比如微博的页面。

点击查看代码
<!DOCTYPE html>
<html lang=zh-cn>

<head>
    <meta charset=utf-8>
    <link rel=dns-prefetch href=//h5.sinaimg.cn>
    <meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no,viewport-fit=cover">
    <meta http-equiv=X-UA-Compatible content="IE=edge">
    <meta http-equiv=Content-Security-Policy content=upgrade-insecure-requests>
    <link rel=icon href=https://weibo.com/favicon.ico>
    <title>微博</title>
    <script>if (window.location.protocol !== 'https:') {
            window.location.href = window.location.href.replace('http:', 'https:');
        }</script>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-019705cd.4b951fca.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-04dd4069.47a5a2b0.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-0b2f6aca.2c8e2b71.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-18576fbb.f6c6c607.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-1cdfc59c.8d2e27e7.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-4993102d.ca64ac98.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-5f89d2e3.79331698.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-62a8d106.8bb819a9.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-66e50bef.d2252512.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-75d4b860.df0d4622.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-77f0cd56.b94f8978.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-8549274a.da4619ac.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-87c041fe.3e3f0add.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-912eab54.2e1914b9.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-997e78d4.ed60a9c7.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-b345e28c.66f5e110.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/chunk-b383583a.81706f3f.css rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-019705cd.db14e1a1.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-04dd4069.9bf00153.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-0b2f6aca.ddcea76a.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-18576fbb.38fac170.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-1cdfc59c.3d0dc360.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-4993102d.930c77e6.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-5f89d2e3.5143b4e4.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-62a8d106.092acbad.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-66e50bef.dc419603.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-71694339.9ed5cb74.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-75d4b860.1240ee46.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-77f0cd56.73a2869c.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-8549274a.4422d8b0.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-87c041fe.ff6a8614.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-912eab54.6ebcdce7.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-997e78d4.7753d92e.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-b345e28c.4e7da6e5.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/chunk-b383583a.5f2877c8.js rel=prefetch>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/app.5f356a05.css rel=preload as=style>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/vendors.a075dfd4.css rel=preload as=style>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/wooui.a0ce2281.css rel=preload as=style>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/3rdparty.89d5f1eb.js rel=preload as=script>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/app.b10cd422.js rel=preload as=script>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/echarts.ad6d06ad.js rel=preload as=script>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/vendors.878caa8f.js rel=preload as=script>
    <link href=//h5.sinaimg.cn/m/weibo-pro/js/wooui.b2c43bcb.js rel=preload as=script>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/wooui.a0ce2281.css rel=stylesheet>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/vendors.a075dfd4.css rel=stylesheet>
    <link href=//h5.sinaimg.cn/m/weibo-pro/css/app.5f356a05.css rel=stylesheet>
</head>

<body>
    <script>window.$VERSION = {
            CLIENT: 'v2.27.6',
            SERVER: 'v2021.11.26.1'
        };

        try { window.$CONFIG = { "enableSweibocom": true, } }  catch (e) { window.$CONFIG = {}; }

        const s = document.createElement('script');
        s.src = 'http://i.sso.sina.com.cn/js/qrcode_login.js';
        document.body.appendChild(s);</script>
    <div id=app></div>
    <script src=//h5.sinaimg.cn/m/weibo-pro/js/3rdparty.89d5f1eb.js></script>
    <script src=//h5.sinaimg.cn/m/weibo-pro/js/echarts.ad6d06ad.js></script>
    <script src=//h5.sinaimg.cn/m/weibo-pro/js/wooui.b2c43bcb.js></script>
    <script src=//h5.sinaimg.cn/m/weibo-pro/js/vendors.878caa8f.js></script>
    <script src=//h5.sinaimg.cn/m/weibo-pro/js/app.b10cd422.js></script>
</body>

</html>

所以为了获取到对应的页面,可以采用分析页面的Ajax接口来获取资源、也可以使用selenium、splash等来模拟对JavaScript的渲染。

1.4 会话(session)和Cookies

在介绍会话和Cookies之前先考虑静态网页和动态网页的区别。对于一个静态网页来说,通过URL访问的页面始终是一致的,加载速度快、代码简单,但是缺少交互性,而动态页面课以通过URL传递各种参数,从而实现网页的交互,比如登录功能。而此时就出现一个问题,登录和未登录所看到的页面是不同的,而每次访问页面的时候都需要登录肯定是难以忍受的。所以就必须要用一些东西来记录登录的状态,他们就是会话和cookies。

1.4.1 无状态HTTP

不能记录客户端状态的HTTP称为无状态HTTP,服务器不知道客户端的状态,所以在页面跳转的时候,每次都会处理之前处理过的信息,造成资源的浪费,所以就使用了会话和cookies来记录客户端的状态。

1.4.2 会话

会话是服务器对一个客户端的记录对象,当用户在页面间跳转的时候,会话会记录客户端的状态,而没有会话的用户则会创建一个会话。

1.4.3 Cookies

Cookies是保存在客户端的身份证明,在客户端首次请求服务器的时候,在响应头里会有叫做set-cookies的内容,而客户端会把这些内容保存下来,之后再对服务器请求时,请求头中会包括cookies的内容,这样服务器就能根据cookies找到该客户端对应的会话,如果找不到对应的会话,证明会话已经过期,这是会产生错误或者重新跳转到登录界面。

1.4.4 会话和Cookies的生命周期

会话和Cookies分别存在于服务器和客户端中,Cookies经常被存在内存之中,而当浏览器关闭时,Cookies就会消失,但此时相对应的会话并不会因此消失,所以就需要服务器对会话设置一个最长保持实现,超过这个时间的会话会被自动销毁。还有一种例外是Cookies被保存再了硬盘之中,当浏览器再次启动的时候,可以从硬盘载入Cookies,从而找到对应的会话。

1.4.5 Cookies的内容

通过F12可以检查网页对应的cookies包含的内容:

  1. Name:cookie的名称,被创建之后无法修改。
  2. Value:Cookie的值,Unicode字符需要字符编码,二进制需要Base64编码。
  3. Domain:可以访问该cookie的网页的域名
  4. Path:该cookies的使用路径,如果有内容/path/则只能由该路径下的网页访问,如果为/则表示该域名下的所有页面都可以访问
  5. Expires/Max-age:cookies的失效时间。正数表示再该数对应的秒失效,负数表示关闭浏览器时失效。
  6. Size:cookie的大小
  7. HTTPOnly:若为True,表示只有再HTTP头中才会带有该cookie,不能通过document.cookie访问
  8. secure:是否使用安全协议传输

以下为Chrome中添加的cookies属性:

  1. Samesite:对与第三方网站cookies的限制
  2. Smaparty:同上
  3. Priority:cookies的优先级,cookies数量超出限制时,优先级低的cookies会先被清除。

1.5 代理

代理在爬虫中的应用主要是为了伪装IP,因为主流网站都会对IP的频繁访问进行检测,影响爬虫的运行,而是使用代理服务器中转数据,可以降低同一IP的访问频率,从而正常运行。

posted @ 2021-11-27 17:28  kirby0  阅读(150)  评论(0)    收藏  举报