01、通用爬虫和聚焦爬虫
根据使用场景,网络爬虫可以分为通用爬虫和聚焦爬虫两种。
通用爬虫
通用网络爬虫是捜索引擎抓取系统(Baidu、Google、Yahoo等)的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
通用搜索引擎(Search Engine)工作原理
通用网络爬虫 从互联网中搜集网页,采集信息,这些网页信息用于为搜索引擎建立索引从而提供支持,它决定着整个引擎系统的内容是否丰富,信息是否即时,因此其性能的优劣直接影响着搜索引擎的效果。
第一步:抓取网页
搜索引擎网络爬虫的基本工作流程如下:
- 首先选取一部分的种子URL,将这些URL放入待抓取URL队列;
- 取出待抓取URL,解析DNS得到主机IP,并将URL对应的网页下载下来,存储进已下载的网页库中,并将这些URL放进已经抓取URL队列。
- 分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓取URL队列,从而进入下一个循环。
搜索引擎如何获取一个新网站的URL:
- 新网站向搜索引擎主动提交网址
- 在其他网站上设置新网站外链(尽可能处于搜索引擎爬虫爬取范围之内)
- 搜索引擎和DNS解析服务商(如DNSPod等)合作,新网站域名将被迅速抓取。
爬虫限制:
搜索引擎蜘蛛的爬行是被输入了一定的规则的,它需要遵从一些命令或文件的内容,如标注为nofollow的链接,或者是Robots协议。
- rel=“nofollow”,告诉搜索引擎爬虫无需抓取目标页,同时告诉搜索引擎无需将的当前页的Pagerank传递到目标页.
- Robots协议(也叫爬虫协议、机器人协议等),全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。
第二步:数据存储
搜索引擎通过爬虫爬取到的网页,将数据存入原始页面数据库。其中的页面数据与用户浏览器得到的HTML是完全一样的。
搜索引擎蜘蛛在抓取网页时,也做一定的重复内容检测,一旦遇到访问权重很低的网站上有大量抄袭、采集、复制的内容,很可能就不再爬取。
第三步:预处理
搜索引擎将爬虫抓取回来的页面,进行各种步骤的预处理。
- 提取文字
- 中文分词
- 消除噪音(比如版权声明文字、导航条、广告等…)
- 索引处理
- 链接关系计算
- 特殊文件处理
. . .
除了HTML文件之外,搜索引擎通常还能抓取和索引以文字为基础的多种文件类型,如PDF、Word、WPS、PPT、TXT文件等。
但搜索引擎还不能处理图片、视频、Flash这类非文字内容,也不能执行脚本和程序。
第四步:提供检索服务、网站排名
搜索引擎在对信息进行组织和处理后,为用户提供关键字检索服务,将用户检索相关的信息展示给用户。
同时根据页面的PageRank值(链接的访问量排名)来进行网站排名,这让Rank值高的网站在搜索结果中会排名靠前。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200422110725339.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dhbmd0dW8xMTE1,size_16,color_FFFFFF,t_70
局限性
- 通用搜索引擎返回的都是网页,大多情况下,网页里90%的内容对用户来说都是无用的;
- 搜索引擎无法提供针对具体某个用户的搜索结果;
- 图片、数据库、音频、视频多媒体等不能很好地发现和获取;
- 基于关键字的检索,难以支持根据语义信息提出的查询,无法准确理解用户的具体需求。
基于以上情况,聚焦爬虫技术得以广泛应用。
聚焦爬虫, 是"面向特定主题需求"的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于:聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。
02、HTTP和HTTPS
- HTTP协议-80端口
HyperTextTransferProtocol, 超文本传输协议是一种发布和接收HTML页面的方法。 - HTTPS-443端口
HypertextTransferProtocoloverSecureSocketLayer, 简单讲是HTTP的安全版,在HTTP下加入SSL 层。
网络爬虫抓取过程可以理解为模拟浏览器操作的过程。
![在这里插入图片描述](https://img-blog.csdnimg.cn/202004221143147.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dhbmd0dW8xMTE1,size_16,color_FFFFFF,t_70
浏览器发送HTTP请求的过程
- 当用户在浏览器的地址栏中输入一个URL并按回车键之后,浏览器会向HTTP服务器发送HTTP请求。HTTP请求主要分为“Get”和“Post”两种方法。
- 当我们在浏览器输入URLhttp://www.baidu.com的时候,浏览器发送一个Request请求去获取http://www.baidu.com的html文件,服务器把Response文件对象发送回给浏览器。
- 浏览器分析Response中的HTML,发现其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。
- 当所有的文件都下载成功后,网页会根据HTML语法结构,完整的显示出来了。
URL
URL(Uniform/UniversalResourceLocator的缩写):统一资源定位符,是用于完整地描述Internet上网页和其他资源的地址的一种标识方法。
基本格式: scheme://host[:port#]/path/…/[?query-string][#anchor]
- query-string:参数,发送给http服务器的数据
- anchor:锚(跳转到网页的指定锚点位置)
03、客户端HTTP请求
客户端发送一个HTTP请求到服务器的请求消息,包括以下格式:
请求方法Method
根据HTTP标准,HTTP请求可以使用多种请求方法.
HTTP1.0:完善的请求/响应模型,并将协议补充完整,定义了三种请求方法:GET,POST和HEAD方法。
HTTP1.1:在1.0基础上进行更新,新增了五种请求方法:OPTIONS,PUT,DELETE,TRACE和CONNECT方法。
HTTP8种请求方法的具体介绍请看我的另一篇博客:传送门
GET和POST详解:
- GET是从服务器上获取数据,POST是向服务器传送数据
- GET请求参数显示,都显示在浏览器网址上,即“Get”请求的参数是URL的一部分。
- POST请求参数在请求体当中,消息长度没有限制而且以隐式的方式进行发送,通常用来向HTTP服务器提交量比较大的数据(比如请求中包含许多参数或者文件上传操作等),请求的参数包含在“Content-Type”消息头里,指明该消息体的媒体类型和编码。
常用的请求报头
- Host: 主机和端口号
- Connection : 客户端与服务连接类型, 默认为keep-alive
- User-Agent: 客户浏览器的名称
- Accept: 浏览器或其他客户端可以接受的MIME文件类型
- Referer:表明产生请求的网页来自于哪个URL
- Accept-Encoding:指出浏览器可以接受的编码方式。
- Accept-Language:语言种类
- Accept-Charset: 字符编码
- Cookie:浏览器用这个属性向服务器发送Cookie
- Content-Type:POST请求里用来表示的内容类型。
04、HTTP响应
HTTP响应由四个部分组成,分别是: 状态行 、 消息报头 、 空行 、 响应正文
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200422115934392.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dhbmd0dW8xMTE1,size_16,color_FFFFFF,t_70
响应状态码:
- 200: 请求成功
- 302: 请求页面临时转移至新url
- 307和304: 使用缓存资源
- 404: 服务器无法找到请求页面
- 403: 服务器拒绝访问,权限不够
- 500: 服务器遇到不可预知的情况
Cookie和Session
服务器和客户端的交互仅限于请求/响应过程,结束之后便断开,在下一次请求时,服务器会认为新的客户端。为了维护他们之间的链接,让服务器知道这是前一个用户发送的请求,必须在一个地方保存客户端的信息。
- Cookie:通过在客户端记录的信息确定用户的身份。
- Session:通过在服务器端记录的信息确定用户的身份。
关于Cookie和Session的介绍见这里:叮、传送门
05、图片下载器
制作爬虫的基本步骤
- 需求分析(http://image.baidu.com/search/index?tn=baiduimage&word=cat)
- 分析网页源代码,配合F12
- 编写正则表达式或者其他解析器代码
- 存储数据到本地
- 正式编写python爬虫代码
import os
import re
import requests
from colorama import Fore
def download_image(url):
"""
下载图片
:param url:图片的网址
:return:
"""
# 1.向服务器发起http请求
response = requests.get(url)
# 2.获取服务器的响应信息
# 响应信息:status_code, text, url
# print(response.url)
# print(response.content) 返回的是bytes类型的信息
# print(response.text) 返回的是unicode的文本信息
# print(dir(response))
# 获取包含图片url地址的html文档, unicode的文本信息
data = response.text
# 3.编写正则表达式,获取图片的地址
# ObjURL":"http:\/\/img0.imgtn.bdimg.com\/it\/u=2072494435,853546208&fm=214&gp=0.jpg"
# 提取到的url:"http:\/\/img0.imgtn.bdimg.com\/it\/u=2072494435,853546208&fm=214&gp=0.jpg"
# 正则表达式规则: . 代表了除\n之外的任意字符, *代表前一个字符出现0次或者无数次 ?非贪婪模式
# r代表非转义的原始字符串
pattern = r'"objURL":"(.*?)"'
# 4.根据正则表达式寻找符合条件的图片的url
images_url = re.findall(pattern, data)
# 5.下载图片到本地
index = 1
for image_url in images_url:
try:
response = requests.get(image_url)
except Exception as e:
print(Fore.RED + '[-]下载失败:%s' %(image_url))
else:
# 获取图片格式: 方法1:通过os.path.splitext()[-1]
image_format = os.path.splitext(image_url)[-1] # .jpg
# 方法2:通过两次split获取
# image_format = image_url.split('/')[-1].split('.')[-1] # jpg
# print(image_format)
# 生成图片存储的绝对路径
if not os.path.dirname(keyword):
os.mkdir(keyword)
image_filename = os.path.join(keyword, str(index) + '.' + image_format)
with open(image_filename, 'wb') as f:
f.write(response.content)
print(Fore.BLUE + '[+]保存图片%s.%s成功' %(index, image_format))
index += 1
if __name__ == '__main__':
keyword = input('请输入批量下载图片的关键字: ')
url = 'http://image.baidu.com/search/index?tn=baiduimage&word=' + keyword
print(Fore.BLUE + '[+] 正在请求网址: %s' %(url))
download_image(url)