文章目录
一.通用爬虫和聚焦爬虫
根据使用场景,网络爬虫可分为通用爬虫和聚焦爬虫两种。
1.普通爬虫
通用网络爬虫是索引擎抓取系统(Baidu、Google、Yahoo等)的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
(1)通用搜索引擎工作原理
通用网络爬虫从互联网中搜集网页,采集信息,这些网页信息用于为搜索引擎建立索引从而提供支持,它决定着整个引擎系统的内容是否丰富,信息是否即时,因此其性能的优劣直接影响着搜索引擎的效果。
(2)基本工作流程
搜索引擎如何获取一个新网站的URL:
- 新网站向搜索引擎主动提交网址;
- 在其他网站上设置新网站外链;
- 和DNS解析服务商(如DNSPod等)合作,新网站域名将被迅速抓取。
(3)爬虫限制
搜索引擎蜘蛛的爬行是被输入了一定的规则的,它需要遵从一些命令或文件的内容。
- rel=“nofollow”,,告诉搜索引擎爬虫无需抓取目标页,同时告诉搜索引擎无需将的当前页的Pagerank传递到目标页.
- Robots协议(也叫爬虫协议、机器人协议等),全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。
(4)局限性
1.大多情况下,网页里90%的内容对用户来说都是无用的。
2. 搜索引擎无法提供针对具体某个用户的搜索结果。
3. 图片、数据库、音频、视频多媒体等不能很好地发现和获取。
4. 基于关键字的检索,难以支持根据语义信息提出的查询,无法准确理解用户的具体需求。
2.聚焦爬虫
聚焦爬虫,是"面向特定主题需求"的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于:聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。
二.HTTP和HTTPS
- HTTP协议-80端口
HyperTextTransferProtocol, 超文本传输协议是一种发布和接收HTML页面的方法。 - HTTPS-443端口
HypertextTransferProtocoloverSecureSocketLayer, 简单讲是HTTP的安全版,在HTTP下加入SSL 层。
(1)HTTP工作原理
网络爬虫抓取过程可以理解为模拟浏览器操作的过程。
(2)浏览器发送HTTP请求的过程
1.当用户在浏览器的地址栏中输入一个URL并按回车键之后,浏览器会向HTTP服务器发送HTTP请求。HTTP请求主要分为“Get”和“Post”两种方法。
2. 当我们在浏览器输入URLhttp://www.baidu.com的时候,浏览器发送一个Request请求去获取http://www.baidu.com的html文件,服务器把Response文件对象发送回给浏览器。
3.浏览器分析Response中的HTML,发现其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。
3. 当所有的文件都下载成功后,网页会根据HTML语法结构,完整的显示出来了。
(3)URL
URL(Uniform/UniversalResourceLocator的缩写):统一资源定位符,是用于完整地描述Internet上网页和其他资源的地址的一种标识方法。
基本格式: scheme://host[:port#]/path/…/[?query-string][#anchor]
query-string:参数,发送给http服务器的数据
http://www.baidu.com?wd=python
anchor:锚(跳转到网页的指定锚点位置)
三.客户端HTTP请求
1.客户端HTTP请求
客户端发送一个HTTP请求到服务器的请求消息,包括以下格式:
2.请求方法Method
根据HTTP标准,HTTP请求可以使用多种请求方法.
HTTP0.9:只有基本的文本GET功能。
HTTP1.0:完善的请求/响应模型,并将协议补充完整,定义了三种请求方法:GET,POST和HEAD方法。
HTTP1.1:在1.0基础上进行更新,新增了五种请求方法:OPTIONS,PUT,DELETE,TRACE和CONNECT方法。
- Get 和 Post 详解
- GET是从服务器上获取数据,POST是向服务器传送数据。
- GET请求参数显示,都显示在浏览器网址上,即“Get”请求的参数是URL的一部分。
- POST请求参数在请求体当中,消息长度没有限制而且以隐式的方式进行发送,通常用来向HTTP服务器提交量比较大的数据(比如请求中包含许多参数或者文件上传操作等),请求的参数包含在“Content-Type”消息头里,指明该消息体的媒体类型和编码。
3.常用的请求报头
Referer:表明产生请求的网页来自于哪个URL
Accept-Encoding:指出浏览器可以接受的编码方式。
Accept-Language:语言种类
Accept-Charset: 字符编码
Cookie:浏览器用这个属性向服务器发送Cookie
Content-Type:POST请求里用来表示的内容类型。
四.HTTP响应
1.HTTP响应
HTTP响应由四个部分组成,分别是: 状态行 、 消息报头 、 空行 、 响应正文
2.响应状态码
200: 请求成功
302: 请求页面临时转移至新url
307和304: 使用缓存资源
404: 服务器无法找到请求页面
403: 服务器拒绝访问,权限不够
500: 服务器遇到不可预知的情况
3.Cookie和Session
服务器和客户端的交互仅限于请求/响应过程,结束之后便断开,在下一次请求时,服务器会认为新的客户端。为了维护他们之间的链接,让服务器知道这是前一个用户发送的请求,必须在一个地方保存客户端的信息。
Cookie:通过在客户端记录的信息确定用户的身份。
Session:通过在服务器端记录的信息确定用户的身份。
五.爬虫案例
1.图片下载器
import re
import requests
import os
def downloadPic(html, keyword):
"""
:param html: 页面源代码
:param keyword: 搜索的关键字
:return:
"""
#(.*?)代表任意多个字符串
#()代表分组,值返回符合条件得字符串中括号里面得内容
pic_url = re.findall('"objURL":"(.*?)",', html, re.S)[:5]
count = 0
print('找到关键词:' + keyword + '的图片,现在开始下载图片...')
# each 是每个图片的url地址
for each in pic_url:
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) '
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 '
'Mobile Safari/537.36'}
# 获取指定图片的相应对象;
response = requests.get(each, timeout=10, headers=headers)
except requests.exceptions.ConnectionError:
print('【错误】当前图片无法下载')
continue
except Exception as e:
print('【错误】当前图片无法下载')
print(e)
continue
else:
# print(response.status_code)
if response.status_code != 200:
print("访问失败: ", response.status_code)
continue
# ******** 存储图片到本地*******************************
if not os.path.exists(imgDir):
print("正在创建目录 ", imgDir)
os.makedirs(imgDir)
posix = each.split('.')[-1]
if posix not in ['png', 'jpg', 'gif', 'jpeg']:
break
print('正在下载第' + str(count + 1) + '张图片,图片地址:' + str(each))
name = keyword + '_' + str(count) + '.' + posix
filename = os.path.join(imgDir, name)
count += 1
with open(filename, 'wb') as f:
# response.content: 返回的是二进制文本信息
# response.text:返回的字符串文本信息
f.write(response.content)
if __name__ == '__main__':
imgDir = 'pictures'
word = input("Input key word: ")
url = 'http://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=' + word
try:
response = requests.get(url)
except Exception as e:
print(e)
content = ''
else:
content = response.text
downloadPic(content, word)