G. B.

个人博客

且将新火试新茶,诗酒趁年华


浅尝爬虫技术

结构

journey 什么是爬虫: 2 需要掌握哪些知识: 3 一个标准操作流程是什么: 4 小例子: 5

什么是爬虫

爬虫的定义非常宽泛,我理解的定义为:通过网络技术将需要的数据或文件从互联网上下载下来。

实际上的爬虫就是一次次独立的网络访问,只不过访问发起者由浏览器或APP变成了编程软件。

这里是知乎上的解释:

2020-12-01-introduction-of-webcrawl-1

爬虫能做什么

  1. 监控各地每日疫情数据的变化
  2. 利用爬虫整合各平台租房信息,并在本地使用elasticsearch检索筛选
  3. Spring在去年开放了375本书的免费下载通道,使用爬虫将它们全部下载下来

爬虫需要掌握哪些知识

2020-12-01-introduction-of-webcrawl-2

什么是HTTP

HTTP是超文本传输协议,1989年诞生,用来在网络上传输文本、图片文件等。

HTTP的特点:

  1. http协议支持客户端/服务端模式,也是一种请求/响应模式的协议。简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、POST。
  2. 灵活:HTTP允许传输任意类型的数据对象。传输的类型由Content-Type加以标记。
  3. 无连接:限制每次连接只处理一个请求。服务器处理完请求,并收到客户的应答后,即断开连接,但是却不利于客户端与服务器保持会话连接,为了弥补这种不足,产生了两项记录http状态的技术,一个叫做Cookie,一个叫做Session。
  4. 无状态:无状态是指协议对于事务处理没有记忆,后续处理需要前面的信息,则必须重传。

URI和URL的区别

HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。

  • URI:Uniform Resource Identifier 统一资源标识
  • URL:Uniform Resource Location 统一资源定位

URI 是用来标示 一个具体的资源的,我们可以通过 URI 知道一个资源是什么。

URL 则是用来定位具体的资源的,标示了一个具体的资源位置。互联网上的每个文件都有一个唯一的URL。

举个例子讲:

2020-12-01-introduction-of-webcrawl-3

通过URL可以在互联网上绝对定位资源;而URI是一个相对路径,只能相对服务器来定位资源。

HTTP报文组成

请求报文构成

  1. 请求行:包括请求方法、URL、协议/版本
  2. 请求头(Request Header)
  3. 请求正文

响应报文构成

  1. 状态行
  2. 响应头
  3. 响应正文

使用浏览器自带的开发者工具,我们可以监控到页面上产生的每一个请求,如下图所示,这是一个GET请求的请求报文和响应报文:

2020-12-01-introduction-of-webcrawl-4

每一次我们使用浏览器访问网站时,这些请求头中的信息都已经由浏览器帮我们自动构建好,但当我们爬虫时,这些信息都需要我们手动构建,大致有两方面原因:

  • header中带验证信息的,如果缺失无法访问成功
  • 伪装我们的请求,让它看起来像是正常访问一样

post和get的区别

  • 都包含请求头请求行,post多了请求body。
  • get多用来查询,请求参数放在url中,不会对服务器上的内容产生作用。post用来提交,如把账号密码放入body中。
  • GET是直接添加到URL后面的,直接就可以在URL中看到内容,而POST是放在报文内部的,用户无法直接看到。
  • GET提交的数据长度是有限制的,因为URL长度有限制,具体的长度限制视浏览器而定。而POST没有。

响应状态码

访问一个网页时,浏览器会向web服务器发出请求。此网页所在的服务器会返回一个包含HTTP状态码的信息头用以响应浏览器的请求。

状态码分类:

  • 1XX- 信息型,服务器收到请求,需要请求者继续操作。
  • 2XX- 成功型,请求成功收到,理解并处理。
  • 3XX - 重定向,需要进一步的操作以完成请求。
  • 4XX - 客户端错误,请求包含语法错误或无法完成请求。
  • 5XX - 服务器错误,服务器在处理请求的过程中发生了错误。

常见状态码:

  • 200 OK - 客户端请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 302 - 临时跳转
  • 400 Bad Request - 客户端请求有语法错误,不能被服务器所理解
  • 401 Unauthorized - 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
  • 404 - 请求资源不存在,可能是输入了错误的URL
  • 500 - 服务器内部发生了不可预期的错误
  • 503 Server Unavailable - 服务器当前不能处理客户端的请求,一段时间后可能恢复正常。

为什么有HTTPS

数据在HTTP协议中传输都是明文发送的,很容易被窃听,并且因为不做身份验证,通信也可能被劫持,导致数据篡改。

HTTPS一般理解为HTTP+SSL/TSL,通过SSL证书验证服务器身份,并为浏览器和服务器之间的通信进行加密。

为什么有websocket

前面讲过http无状态无连接,如果服务器上的资源更新,除非客户端主动请求,服务器在http协议下无法主动推送更新。基于http协议的解决方法就是在客户端实现一个轮询,可以理解为一个loop,例如每隔1秒发送一次访问,但这样做很占用资源,并且有很大一部分是无用请求。

于是就有websocket协议,在第一次http request建立连接之后,连接不会断开,并且通信是双向的。

这种协议对爬虫不太友好,我们入门爬虫只需要关注http协议即可。

什么是API

API是应用程序编程接口(Application Programming Interface),通俗的理解,它是一个没有页面,根据请求只返回json数据的URL。

在前后端分离的网站项目中,前后端通信就是使用json发送数据,根据前端的请求,后端只负责将数据发送给前端,页面由前端负责渲染;而对于一些比较老旧的网站架构,页面是在后端渲染好再发送给前端的。

对于我们爬虫来讲,前后端分离的架构爬取数据最容易,因为可以不用分析页面结构,直接拿到json数据。

什么是XHR

Ajax(Asynchronous Javascript and XML)是使用Javascript的XHR(XMLHttpRequest)对象实现的。XmlHttpRequest 对象允许执行Javascript而无需重新加载完整的网页。AJAX仅发送和接收网页的一部分。

现代网站往往包含有很多图片,尽管图片压缩技术已经很好,但是在网速较慢的情境下,过长时间等待网页加载会流失很多客户。因此,异步加载技术就是让页面的大概轮廓先加载出来,其中的较大资源,例如图片,等待页面框架加载好后再下载。XHR对象可以理解为HTML页面中异步加载部分的占位符。

这对我们爬虫来说,制造了很大的困难,异步加载的资源URL需要我们分析网页源代码并且监控网页流量来获得。

什么是header

每一个http request和response都有一个header,它可以理解为相对于请求主体body来说的元数据,header中附有各种信息,下面是一个http request的例子:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Host: 47.102.97.73
If-Modified-Since: Mon, 04 May 2020 09:58:54 GMT
If-None-Match: "143c-5a4cf9428c5be-gzip"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36

Accept

接受的返回内容数据类型

Accept-Encoding

如果返回内容是压缩格式,指明接受的类型

Accept-Language

这个信息可以说明用户的默认语言设置。如果网站有不同的语言版本,那么就可以通过这个信息来重定向用户的浏览器。

Cache-Control

“max-age” 代表缓存有效的秒数。

Host为请求的主机地址

If-Modified-Since

如果一个页面已经在你的浏览器中被缓存,那么你下次浏览时浏览器将会检测文档是否被修改过,它在请求头中会附件这一条,如果自从这个时间以来未被修改过,那么服务器将会返回“304 Not Modified”,而且不会再返回内容,浏览器将自动去缓存中读取内容。

User-Agent这个头部可以携带如下几条信息:

  • 浏览器名和版本号

  • 操作系统名和版本号

  • 默认语言

这就是某些网站用来收集访客信息的一般手段。例如,你可以判断访客是否在使用手机访问你的网站,然后决定是否将他们引导至一个在低分辨率下表现良好的移动网站。

Python库

需要掌握的库已经列出,这里一一解释各自的用处:

  • re:正则表达式,从文本中筛选需要的信息
  • requests:一个支持GET和POST请求的库
  • lxml:解析html页面,并使用xpath语法定位文档树中的元素,获得想要的部分
  • selenium:当页面使用了大量js、使用了token验证通信、使用ajax异步加载元素,种种原因导致你无法分析出想要数据的URL,或是无法自己手工构建请求访问成功时,这个库可以自动化操作浏览器访问页面,但相比直接请求URL效率非常低
  • logging:python自带的日志库,网络请求的失败率极高,并且稍大规模的数据不是几分钟能爬完的,需要留日志查看运行情况

数据持久化方案

数据应该及时保存在硬盘上,因此掌握一种数据库是必要的,这里简单介绍下各种数据库都能存什么类型的数据。

  • MySQL:关系型数据库,和我们平常使用的impala类似,保存一张张表
  • redis:键值对数据库,保存一个个的键值对
  • mongodb:文档型数据库,保存json类型的数据
  • sqlite:一个轻量的关系型数据库,保存的数据在文件系统中只会生成一个文件,常用作嵌入式数据库

前端

HTML是超文本标记语言,是一种标识性的语言。它与css和js经常一同使用。css是用来格式化页面的,使页面有美观的样式,但css的效果是静态的。js是一种脚本语言,页面上的动态化效果,包括ajax都是由它完成的。

我们的浏览器将html文件和css、js文件组织在一起,渲染为一个页面。

html有很多标签,通过不同的标签组织页面的结构,最终生成一个文档树,每一个元素都是树的一部分,我们通过在文档树中使用xpath语法定位想要的元素来获取需要的数据。

一个标准操作流程是什么

  1. 在浏览器中打开想要爬取的页面
  2. 打开开发者工具,刷新页面,查看访问流量
  3. 定位到想要的数据是哪一个请求返回的,分析该请求的header
  4. 如果该header没有token验证,且返回的数据是json,则伪造一个header发送请求拿到数据
  5. 如果返回的数据是一个页面,则分析数据如何在页面中使用xpath定位,之后发送请求在文档树中定位出数据
  6. 如果页面是动态的,则使用模拟浏览器访问。

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦