1 爬虫简介
爬虫的主要工作:
- 获取网页源代码。
- 从网页源代码中解析和提取所需的数据。
两者相比,获取网页源代码是一切爬虫项目的核心,只要能提取网页源代码,就有很多手段来解析和提取数据。
所有想要获取的内容(新闻标题、网址、日期、来源等)都在网页源代码中。
要对数据进行处理和分析,首先就要拥有数据。在当今的互联网时代,大量信息以网页为载体,因此网页成为一个很重要的数据来源。
爬虫是指按照一定的规则自动从网页上抓取数据的代码或脚本,其能模拟浏览器对存储指定网页的服务器发起请求,从而获得网页的源代码,进而从网页源代码中提取需要的数据。
开发者通过编写程序,模拟人类浏览器上网,让其去互联网上抓取数据的过程。一种按照一定的规则,自动抓取互联网信息的程序。
- 原则上只要是客户端(浏览器)能做的事情,爬虫都能做。
- 爬虫也只能获取客户端(浏览器)所展示出来的数据。
网页端源代码规定了网页中显示的文字、图片等信息的内容和格式,我们要提取的数据就藏在源代码中。
小结:模拟浏览器,发送请求,获取响应。
获取网页源代码有两个核心的库:Requests库和Selenium库。这两个库能获取95%的网页源代码。
剩下的网页存在IP地址反扒、验证码反爬等限制爬取的措施。
2 爬虫的价值
抓取互联网上的数据,为我所用。有了大量的数据,就如同有了一个数据银行,下一步就是如何将这些爬取的数据产品化、商业化。随着大数据时代的来临,爬虫技术的应用会越来越广泛。
1.数据采集
- 抓取微博评论(机器学习舆情控制)
- 抓取招聘网站的招聘信息(数据分析、挖掘)
- 新浪滚动新闻
- 百度新闻网站
2.软件测试
- 爬虫之自动化测试
- 虫师
3.12306抢票
4.网站上的投票
- 投票网
5.网络安全
- 短信轰炸
- 注册页面
- web漏洞扫描
3 法律相关
- 在法律中,爬虫技术是不被禁止的。
- 具有违法风险。
3.1 爬虫分类
数量、是否获取数据和url和数据的关系。
爬虫分为:通用爬虫,聚焦爬虫和增量式爬虫。
爬虫带来的风险体现在如下两方面:
- 爬虫干扰了被访问网站的正常运营。
- 爬虫抓取了收到法律保护的特定类型的数据或信息。
3.1.1 通用爬虫
抓取系统的重要组成部分,抓取的是互联网上一整张页面数据。(例如搜索引擎)
3.1.2 聚焦爬虫
爬取网站数量有上限,有明确的目标。
建立在通用爬虫的基础之上,抓取的是页面中特定的局部内容,即专门抓取某一类(某一个)网站数据。(例如12306抢票)
3.1.3 增量式爬虫
获取数据用于后续分析。
监测网站中数据更新的情况,只会抓取网站中最新更新出来的数据。
根据url地址和对应的页面内容是否改变,数据增量爬虫可以分为:
- 基于url地址变化,内容也随之变化的数据增量爬虫(整条更新)
- url地址不变,内容变化的数据增量爬虫(数据部分更新)
3.2 使用爬虫的注意事项
- 时常优化自己的程序,避免干扰被访问网站的正常运行。
- 在使用或传播爬取到的数据时,需要额外审查抓取到的内容,如果发现到了涉及用户隐私或商业机密等敏感内容,开发者需要及时停止爬取或传播。
4 反爬机制
相关门户网站可以通过指定相应的策略或者技术手段,防止爬虫程序进行网站数据的爬取。
5 反反爬策略
爬虫程序可以通过指定相关的策略或者技术手段,破解门户网站中具备的反爬机制,从而可以获取门户网站中的数据。
5.1 UA(User-Agent)伪装
门户网站的服务器会监测对应请求的载体身份标识,如果监测到请求的载体身份标识为某一款浏览器,那么就说明该请求就是一个正常的请求(用户通过浏览器发起的请求),但是如果监测到的载体身份标识不是基于某一款浏览器的,那么该请求就为不正常的请求(爬虫),因此服务器端就很有可能拒绝请求。
因此,让爬虫对应的请求伪装为某一款浏览器。
有时候不进行UA伪装也可以获得网页源代码,但是UA伪装的设置和使用并不麻烦,且可以避免可能的爬取失败。
6 robots.txt协议
“君子协议”,明确规定了哪些数据可以被爬取,哪些数据不可以被爬取。
7 http协议
7.1 基础概念
服务器和客户端进行数据交互的一种形式。(应用层的协议)
发送请求,获取响应(http/https协议)
7.1.1 http以及https的概念和区别
https比http更安全,但是性能更低。
- http:超文本传输协议,默认端口号是80
- 超文本:是指超过文本,还包括图片、音频、视频等文件。
- 传输协议:是指使用共用约定的固定格式来传递转换成字符串的超文本内容。
- https:http +ssl(安全套接字层),即带有安全套接字层的超文本传输协议,默认端口号是443
- ssl对传输的内容(超文本,也就是请求体或者响应体)进行加密
- 可以打开浏览器访问一个url,右键检查,点击network,点选一个url,查看heetp协议的形式
网址构成与网址简化
有时候浏览器地址中的网址很臃肿,开发者可以将网址中(?)后的网址参数删除,删除后如能正常访问,便说明这些参数是不必要的,因此我们可以使用这些方法来简化网址。
网址中中文变成英文和数字
有时候复制网址后,其中的中文编程了英文和数字等其他字符。这是因为浏览器默认识别的是英文字符,中文字符需要转换成英文字符,浏览器才能识别。这些转换后的英文、数字等字符的组合就可以看成中文翻译成英文后的样子,我们同样可以将这样一串特殊字符改成原本的中文。
7.2 常用请求头信息
参数headers用于向网站提供访问者的信息,其中的User-Agent(用户代理)反应访问者使用的何种浏览器。
- Content-type(请求内容的类型)
- Host(域名,即主机和端口号)
- Connection(链接类型)
- Upgrade-Insecu-Requests(升级为HTTPS请求)
- User-Agent(浏览器名称)
- Referer(页面跳转处)
- Cookie(Cookie)
- Authorizatio(用于表示HTTP协议中需要认证资源的认证信息)
加粗的请求头为常用的请求头,在服务器被用来进行爬虫识别的频率最高,相较于其余的请求头更为重要,但是这里需要注意的是并不意味着其余的不重要。因为有的网站的运维和开发人员可能会剑走偏锋,会使用一些不常见的请求头来进行爬虫的甄别。
7.2.1 User-Agent
用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等,即请求载体的身份标识。
7.2.2 Connection
请求完毕后,是断开连接还是保持连接。
7.3 常用响应头信息
7.3.1 Content-type
服务器响应客户端的数据类型。
8 https协议
安全的超文本传输协议。
8.1 数据加密
- 对称密钥加密:对称密钥加密又叫专用密钥加密或共享密钥加密,即发送和接收数据的双方必使用相同的密钥对明文进行加密和解密运算。
- 非对称密钥加密:非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
- 证书密钥加密:非对话密钥加密的缺点,第一就是公钥可能存在被挟持的情况,无法保证客户端收到公开密钥就是服务器发行的公开密钥。此时就引出了公开密钥证书机制。数字证书认证机构就是客户端与服务器都可信赖的第三方机构。
9 requests模块
9.1 基础简介
Python中原生的一块基于网络请求的模块,功能非常强大,使用起来非常简单便捷,效率极高。
主要作用:模拟浏览器发送请求。
9.2 如何使用(requests模块的编码流程)
第一步:指定URL(即网址)。
统一资源定位标识符(URL)是因特网的万维网服务程序上用于指定信息位置的表示方法。
第二步:基于requets模块,发起请求。
第三步:获取响应数据。
第四步:持久化存储数据。
Requests模块的弱点
使用Requests模块获取的是未经渲染的原始网页源代码,但是若用Requests模块爬取使用动态渲染的网页,所爬取的结果往往不包含我们想要的信息。
快速验证网页是否被动态渲染
右键查看网页源代码,若查看的网页源代码较少,也不包含用开发者工具查看的信息,变判定为开发者工具看到的网页源代码是动态渲染的结果。
爬取被动态渲染的网页,需要使用Selenium模块打开模拟浏览器访问网页,获取渲染后的网页源代码。
Requests模块和Selenium模块的比较
Requests模块直接访问网页,爬取速度非常快。
Selenium模块先打开模拟浏览器,再访问网页,导致爬取速度很慢。
实战中,通常将两个库结合起来使用,实现优势互补。
10 爬虫的流程
1、url发送请求,获取响应。
2、解析响应。
3、如果从响应中提取url,则继续发送请求,获取响应。
4、如果从响应中中提取数据,则将数据进行保存。
11 查看网页源代码
推荐使用谷歌浏览器(chrome),只要按F12键便能显示网页源代码。
开发者工具
按下F12键,窗口下方会出现一个开发者工具界面,是进行数据挖掘的利器。
一般我们只需要用到两个工具:元素选择工具和Elements选项卡。
注意:右键快键菜单看到的源代码和使用开发者工具所看到的代码有时候不尽相同。
- 前者是网站服务器返回给浏览器的原始代码。
- 后者是浏览器对原始代码做了错误修正和动态渲染的结果。
实战经验
现有开发者工具初步了解网页结构,再右键快捷参看查看网页原始代码,同时利用Crtl + F进行搜索,确定目标数据在网页源代码中的位置。
12 Selenium模块
访问并关闭模拟浏览器
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://www.baidu.com')
browser.quit()
获取网页源代码
data = browser.pag_source
13 数据解析和提取
解析网页源代码的方法有很多,主流的方法有正则表达式解析法、BeautiSoup解析法、pquery解析法、XPath解析法等。
13.1 正则表达式解析和提取数据
正则表达式是一种非常好用的信息提取手段,它可以高效地从文本中提取所需信息。掌握了正则表达式后,不仅可以在爬虫任务中从网页源代码中提取信息,还可以在其他非爬虫任务中从普通文本中提取信息。
13.2 findall()函数
re库中的findall()函数提取文本。findall()函数可在原始文本中寻找所有符合匹配规则的文本。
基础语法如下:
re.findall(匹配规则,原始文本)
findall()函数返回的是一个包含提取结果的列表,其中的列表中的元素都是从原始文本提取出来的。
13.3 正则表达式:非贪婪匹配(.*?)
(.*?)用于提取文本A和文本B之间的内容,并不需要直到内容的确切长度和格式,但是需要知道内容位于那两串文本之间。
基础语法如下:
文本A(.*?)文本B
演示如下:
import re
content = '文本A百度新闻文本B'
p_source = '文本A(.*?)文本B'
source = re.findall(p_source, content)
print(content)
一般不将匹配规则直接写在findall()函数的括号中,而是分成两行,先写匹配规则,再调用findall()函数。
在正常实践中,满足匹配非贪婪匹配的内容通常不止一个,那么findall()函数会从字符串的起始位置开始寻找文本A,找到后开始寻找文本B,当找到第一个文本A后,暂时停止寻找,将文本A与文本B之间的内容存入到列表中,然后继续寻找文本A,重复之前的操作,直到到达字符串的结束位置,并将所有匹配的内容存入列表。
编写正则表达式的过程就是一个找规律的过程。如果有class属性,通常会用class属性作为强定位属性,并最终根据Python获取的网页源代码来编写正则表达式。
13.4 正则表达式:非贪婪匹配.*?
.?用于代替文本C和文本D之间的所有内容。之所以要使用“.?,是因为文本C和文本D之间的内容经常变动或没有规律,无法写到匹配规则里;或者文本C和文本D之间的内容较多,我们不想写到匹配规则里。
13.5 正则表达式:自动换行的修饰符re.S
让findall()函数在查找时可以自动考虑换行的影响,使得非贪婪匹配可以匹配换行。
基础语法如下:
re.findall(匹配规则, 原始文本, re.S)
13,6 正则表达式:sub()函数
基础语法如下:
re.sub(需要替换的内容, 替换值, 原字符串)
该函数主要用于清洗正则表达式提取出的内容。
13.7 正则表达式:中括号“[ ]”的用法
使用中括号取消这些符号的特殊含义。