Python 网络爬虫与数据采集
第1章 序章 网络爬虫基础
1 爬虫基本概述
1.1 爬虫是什么
1.2 爬虫可以做什么
- 搜索引擎
- 采集金融数据
- 采集商品数据
- 采集竞争对手的客户数据
- 采集行业相关数据,进行数据分析
- 刷流量
1.3 爬虫的分类
- 通用网络爬虫
又称为全网爬虫,其爬取对象由一批 URL 扩充至整个 Web,主要由搜索引擎或大型 Web 服务商使用。 - 聚焦网络爬虫
又称为主题网络爬虫,其特点是只选择性的地爬取与预设的主题相关的页面,相比通用网络爬虫,聚焦网络爬虫仅需要爬取与主题相关的页面,极大地节省硬件及网络资源,能更快的更新保存页面,更好的满足特定人群对特定领域的需求。 - 增量网络爬虫
只对已下载的网页采取增量式更新,或只爬取新产生的及已经发生变化的网页,这种机制能够在某种程度上保证所爬取的网页尽可能的新。 - 深度网络爬虫
Web 页面按照存在的方式可以分为表层页面和深层页面两类。表层页面是只传统搜索引擎可以索引到的页面,以超链接可以达到的静态页面为主。深层页面是指大部分内容无法通过静态链接获取,隐藏在搜索表单之后的,需要用户提交关键词后才能获得的 Web 页面,如一些登陆后可见的网页。
1.4 爬虫的基本流程
1.4.1 浏览网页的流程

图 1.1: 浏览网页的流程
1.4.2 爬虫的基本流程
- 请求网页
通过 HTTP 库向目标站点发起请求,即发送一个 Request,请求可以包含额外的 headers 等
信息,等待服务器响应! - 获得相应内容
如果服务器能正常响应,会得到一个 Response,Response 的内容便是所要获取的页面内容,
类型可能有 HTML,Json 字符串,二进制数据(如图片视频)等类型。 - 解析内容
得到的内容可能是 HTML,可以用正则表达式、网页解析库进行解析。可能是 Json,可以
直接转为 Json 对象解析,可能是二进制数据,可以做保存或者进一步的处理。 - 存储解析的数据
保存形式多样,可以存为文本,也可以保存至数据库,或者保存特定格式的文件
测试案例
代码 0-0: 爬取搜狗首页的页面数据
#导 包 import requests #step_1 : 指 定 url url = ’https :// www . sogou . com /’ #step_2 : 发 起 请 求 : #使 用 get 方 法 发 起 get 请 求 , 该 方 法 会 返 回 一 个 响 应 对 象 。 参 数 url 表 示 请 求 对 应 的 url response = requests . get ( url = url ) #step_3 : 获 取 响 应 数 据 : #通 过 调 用 响 应 对 象 的 text 属 性 , 返 回 响 应 对 象 中 存 储 的 字 符 串 形 式 的 响 应 数 据 ( 页 面 源 码 数 据 ) page_text = response . text #step_4 : 持 久 化 存 储 with open (’sogou . html ’,’w’, encoding =’utf -8’) as fp: fp . write ( page_text ) print (’ 爬 取 数 据 完 毕 ! ! ! ’) 1.5 爬虫与反爬虫
- 爬虫:使用任何技术手段,批量获取网站信息的一种方式。关键在于批量。
- 反爬虫:使用任何技术手段,阻止别人批量获取自己网站信息的一种方式。关键也在于批量。
- 误伤:在反爬虫的过程中,错误的将普通用户识别为爬虫。误伤率高的反爬虫策略,效果再好也不能用。
- 拦截:成功地阻止爬虫访问。这里会有拦截率的概念。通常来说,拦截率越高的反爬虫策略,误伤的可能性就越高。因此需要做个权衡。
- 资源:机器成本与人力成本的总和。
1.5.1 爬虫的攻与防
- 攻:
Day 1 小莫想要某站上所有的电影,写了标准的爬虫 (基于 HttpClient 库),不断地遍历某站的电影列表页面,根据 Html 分析电影名字存进自己的数据库。 - 守:
Day 1 这个站点的运维小黎发现某个时间段请求量陡增,分析日志发现都是IP(xxx.xxx.xxx.xxx) 这个用户,并且 user-agent 还是 Python-urllib/3.6 ,基于这两点判断非人类后直接在服务器上封杀。 - 攻:
Day 2 小莫电影只爬了一半,于是也针对性的变换了下策略:1. user-agent 模仿百度(“Baiduspider…”),2IP 每爬半个小时就换一个 IP 代理。 - 守:
Day 2 小黎也发现了对应的变化,于是在服务器上设置了一个频率限制,每分钟超过 120次请求的再屏蔽 IP。同时考虑到百度家的爬虫有可能会被误伤,想想市场部门每月几十万的投放,于是写了个脚本,通过 hostname 检查下这个 ip 是不是真的百度家的,对这些 ip 设置一个白名单。 - 攻:
Day 3 小莫发现了新的限制后,想着我也不急着要这些数据,留给服务器慢慢爬吧,于是修改了代码,随机 1-3 秒爬一次,爬 10 次休息 10 秒,每天只在 8-12,18-20 点爬,隔几天还休息一下。 - 守:
Day 3 小黎看着新的日志头都大了,再设定规则不小心会误伤真实用户,于是准备换了一个思路,当 3 个小时的总请求超过 50 次的时候弹出一个验证码弹框,没有准确正确输入的话就把 IP 记录进黑名单。 - 攻:
Day 4 小莫看到验证码有些傻脸了,不过也不是没有办法,先去学习了图像识别(关键词PIL,tesseract),再对验证码进行了二值化,分词,模式训练之后,总之最后识别了小黎的验证码(关于验证码,验证码的识别,验证码的反识别也是一个恢弘壮丽的斗争史…),之后爬虫又跑了起来。 - 守:
Day 4 小黎是个不折不挠的好同学,看到验证码被攻破后,和开发同学商量了变化下开发模式,数据并不再直接渲染,而是由前端同学异步获取,并且通过 JavaScript 的加密库生成动态的 token,同时加密库再进行混淆(比较重要的步骤的确有网站这样做,参见淘宝和微博的登陆流程)。 - 攻:
Day 5 混淆过的加密库就没有办法了么?当然不是,可以慢慢调试,找到加密原理,不过小莫不准备用这么耗时耗力的方法,他放弃了基于 HttpClient 的爬虫,选择了内置浏览器引擎的爬虫 (关键词:PhantomJS,Selenium),在浏览器引擎运行页面,直接获取了正确的结果,又一次拿到了对方的数据。 - 守:
Day 5 小黎:…
1.5.2 常见的反爬与反反爬
- 可以专门写一个在网上抓取可用代理 ip 的脚本,然后将抓取到的代理 ip 维护到代理池中供爬虫使用,当然,实际上抓取的 ip 不论是免费的还是付费的,通常的使用效果都极为一般,如果需要抓取高价值数据的话也可以考虑购买宽带 adsl 拨号的 VPS,如果 ip 被目标网站被封掉,重新拨号即可。
- 降低请求频率。例如每个一个时间段请求一次或者请求若干次之后 sleep 一段时间。由于网站获取到的 ip 是一个区域网的 ip,该 ip 被区域内的所有人共享,因此这个间隔时间并不需要特别长, 对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。对于有逻辑漏洞的网站,可以通过请求几次,退出登录,重新登录,继续请求来绕过同一账号短时间内不能多次进行相同请求的限制,如果能有多个账户,切换使用,效果更佳。
- 神经网络训练 NLP(图像识别)
- 人工识别
- 打码平台
- 第三方 OCR 库
守: 动态页面的反爬虫 (通过变换网页结构反爬)
一些社交网站常常会更换网页结构,而爬虫大部分情况下都需要通过网页结构来解析需要的数据,所以这种做法也能起到反爬虫的作用。在网页结构变换后,爬虫往往无法在原本的网页位置找到原本需要的内容.
破:应对措施: - 只爬取一次时,在其网站结构调整之前,将需要的数据全部爬取下来;使用脚本对网
站结构进行监测,结构变化时,发出告警并及时停止爬虫。 - 逆向分析,抓包
- selenium 库
1.6 爬虫的合法性与 robots 协议
1.6.1 robots 协议
robots 协议也称作爬虫协议、机器人协议,它的全名叫作网络爬虫排除标准(Robots Exclusion Protocol ),当使用一个爬虫爬取一个网站的数据时,需要遵守网站所有者针对所有爬虫所制定的协议! 简单说就是是一种存放于网站根目录下的 ASCII 编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的。
robots . txt 的 样 例 User - agent : * Disallow : / Allow : / public /
User - agent : * Disallow : /
允许所有爬虫访问任何目录的代码如下:
User – agent : * Disallow :
禁止所有爬虫访问网站某些目录的代码如下:
User - agent : * Disallow : / private / Disallow : / tmp /
只允许某一个爬虫访问的代码如下:
User - agent : WebCrawler Disallow : User - agent : * Disallow : /
1.6.2 查看网页的 robots 协议
❖ 合法的爬虫
- 遵守 Robots 协议
Robots 协议也叫 robots.txt(统一小写)是一种存放于网站根目录下的 ASCII 编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的。Robots 协议就是告诉爬虫,哪些信息是可以爬取,哪些信息不能被爬取,严格按照Robots 协议爬取网站相关信息一般不会出现太大问题。 - 不能造成对方服务器瘫痪
但不是说只要遵守 Robots 协议的爬虫就没有问题,还涉及到两个因素,第一不能大规模爬虫导致对方服务器瘫痪,这等于网络攻击。2019 年 05 月 28 日国家网信办发布的《数据安全管理办法(征求意见稿)》中,拟通过行政法规的形式,对爬虫的使用进行限制:网络运营者采取自动化手段访问收集网站数据,不得妨碍网站正常运行;此类行为严重影响网站运行,如自动化访问收集流量超过网站日均流量三分之一,网站要求停止自动化访问收集时,应当停止。 - 不能非法获利
恶意利用爬虫技术抓取数据,攫取不正当竞争的优势,甚至是牟取不法利益的,则可能触犯法律。实践中,非法使用爬虫技术抓取数据而产生的纠纷其实数量并不少,大多是以不正当竞争为由提请诉讼。
❖ 违法的爬虫
- 爬虫不能涉及个人隐私!
“一个程序员写了个爬虫程序,整个公司 200 多人被端了。”如果爬虫程序采集到公民的姓名、身份证件号码、通信通讯联系方式、住址、账号密码、财产状况、行踪轨迹等个人信息,并将之用于非法途径的,则肯定构成非法获取公民个人信息的违法行为。也就是说你爬虫爬取信息没有问题,但不能涉及到个人的隐私问题,如果涉及了并且通过非法途径收益了,那肯定是违法行为。
另外,还有下列三种情况,爬虫有可能违法,严重的甚至构成犯罪: - 爬虫程序规避网站经营者设置的反爬虫措施或者激活成功教程服务器防抓取措施,非法获取相
关信息,情节严重的,有可能构成“非法获取计算机信息系统数据罪”。 - 爬虫程序干扰被访问的网站或系统正常运营,后果严重的,触犯刑法,构成“破坏计
算机信息系统罪” - 爬虫采集的信息属于公民个人信息的,有可能构成非法获取公民个人信息的违法行为,
情节严重的,有可能构成“侵犯公民个人信息罪”。
1.7 Python 爬虫相关库
❖ 请求库
- urllib3 库
提供很多 Python 标准库里所没有的重要特性:线程安全,连接池,客户端 SSL/TLS验证,文件分部编码上传,协助处理重复请求和 HTTP 重定位,支持压缩编码,支持HTTP 和 SOCKS 代理,100% 测试覆盖率
- urllib 库
Python 内置的 HTTP 请求库,提供一系列用于操作 URL 的功能
- requests 库
❖ 解析库
- 正则表达式
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。正则表达式是繁琐的,但它是强大的
- lxml 的
- C 语言编写高效 HTML/XML 处理库。支持 HTML 和 XML 的解析,也支持 XPath 解析方式,而且解析效率非常高。
- xpath 库
XPath,全称 XML Path Language,即 XML 路径语言,它是一门在 XML 文档中查找信息的语言。XPath 最初设计是用来搜寻 XML 文档的,但是它同样适用于 HTML 文档的搜索。
- BeautifulSoup 库
- MySQL 数据库与 PyMySQL 库
MySQL一个轻量级的关系型数据库,PyMySQL是在Python3.x版本中用于连接MySQL服务器的一个库。
- MongoDB 数据库与 PyMongo
- crapy
一个为了爬取网站数据,提取结构性数据而编写的应用框架
2. Chrome 浏览器开发者工具
2.1 Chrome 浏览器开发者工具简述
2.1.1 什么是浏览器开发者工具
其实简单的说,浏览器开发者工具就是给专业的 web 应用和网站开发人员使用的工具,它的作用在于,帮助开发人员对网页进行布局,比如 HTML+CSS,帮助前端工程师更好的调试脚本(JavaScript、jQuery)之类的,还可以使用工具查看网页加载过程,获取网页请求(这个过程也叫做抓包),抓包是非常有意思的过程,而每一个浏览器厂商生产出来的浏览器都会有自己的杀手锏,也就是功能上的差别,那么这个时候你就找一个最适合自己的浏览器使用就可以,接下来就是介绍我常用的三个浏览器。
2.1.2 浏览器开发者工具基本使用
2.2 浏览器开发者工具面板说明
2.2.1 元素 (Elements) 面板
2.2.2 网络 (Network) 面板 (1)

图 2.9: 浏览器开发者工具
查看一些请求的名字,状态码,类型,大小和类型! 这个不是重点!重点是这个资源本身的一些属性!
2.2.3 网络 (Network) 面板 (2)
3. HTTP 协议
3.1 HTTP 简介
3.2 主要特点
3.3 URL,URI,URN
3.3.1 URI* 统一资源标识符
HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。URL是一种特殊类型的 URI,包含了用于查找某个资源的足够的信息URI (Uniform Resource Identifier) 即统一资源标志符
3.3.2 URL* 统一资源定位符
3.3.3 URN* 统一资源名称
- urn:isbn:0 (其 ISBN 编号,以确定一本书)
- urn:uuid:6e8bc430-9c3a-11d9-9669-0c9a66 (一个全局唯一标识符)
- urn:publishing:book (标识文档作为一个图书类型的 XML 命名空间)
- urn: isbn:0 指定了一本书的 ISBN, 可以唯一标识这本书,但是没有指定到哪里定位这本书
3.3.4 URI,URL,URN 的区别
3.4 HTTP 协议与 HTTPS 协议
3.4.1 HyperText
3.4.2 HTTP 与 HTTPS
- 苹果公司强制所有 iOS App 在 2017 年 1 月 1 日前全部改为使用 HTTPS 加密,否则 App 就 无法在应用商店上架
- 谷歌从 2017 年 1 月推出的 Chrome 5 6 开始,对未进行 HTTPS 加密的网址链接亮出风险提 示,即在地址栏的显著位置提醒用户“此网页不安全”
- 腾讯微信小程序的官方需求文档要求后台使用 HTTPS 请求进行网络通信,不道足条件的域 名和协议无法请求
3.5 HTTP 请求过程
3.5.1 General
3.5.2 请求方法 (Request Method)
3.5.3 状态码 (Status Code)
3.5.4 请求头信息 (Request Headers)
请求头信息用来说明服务器要使用的附加信息,比较重要的信息有 Cookie、Referer、User-Agent
Python Code: GET /home.html HTTP/1.1 Host: developer.mozilla.org User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/ Firefox/50.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://developer.mozilla.org/testpage.html
Connection: keep-alive Upgrade-Insecure-Requests: 1 If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a" Cache-Control: max-age=0
3.5.5 响应头信息 (Response Headers)
响应报文:当收到 get 或 post 等方法发来的请求后,服务器就要对报文进行响应。
Python Code: 200 OK Access-Control-Allow-Origin: * Connection: Keep-Alive Content-Encoding: gzip Content-Type: text/html; charset=utf-8 Date: Mon, 18 Jul 2016 16:06:00 GMT Etag: "c561c68d0ba92bbeb8b0f612a9199f722e3a621a" Keep-Alive: timeout=5, max=997 Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT Server: Apache Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=; Path=/; secure Transfer-Encoding: chunked Vary: Cookie, Accept-Encoding X-Backend-Server: developer2.webapp.scl3.mozilla.com X-Cache-Info: not cacheable; meta data too large X-kuma-revision: x-frame-options: DENY
3.5.6 响应体 (Response Body)
3.6 Cookies 和 session
3.6.1 Cookies
3.6.2 session
3.6.3 Cookies 和 session 区别
Cookies 是一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术。Cookies 是当你浏览某网站时,由 Web 服务器置于你硬盘上的一个非常小的文本文件,它可以记录你的用户 ID、密码、浏览过的网页、停留的时间等信息。session:当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个Session 对象。当会话过期或被放弃后,服务器将终止该会话。cookie 机制:采用的是在客户端保持状态的方案,而 session 机制采用的是在服务端保持状态的方案。同时我们看到由于服务器端保持状态的方案在客户端也需要保存一个标识,所以 session 机制可能需要借助 cookie 机制来达到保存标识的目的。Session 是服务器用来跟踪用户的一种手段,每个 Session 都有一个唯一标识:session ID。当服务器创建了 Session 时,给客户端发送的响应报文包含了 Set-cookie 字段,其中有一个名为 sid的键值对,这个键值 Session ID。客户端收到后就把 Cookie 保存浏览器,并且之后发送的请求报表都包含 SessionID。HTTP 就是通过 Session 和 Cookie 这两个发送一起合作来实现跟踪用户状态,Session 用于服务端,Cookie 用于客户端。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216614.html原文链接:https://javaforall.net
