Chapter05 | 抓取策略与爬虫持久化
互联网中的网络之间互相连接,构成一个巨大的网络图:
网络爬虫就是从这个巨大复杂的网络体中,根据给定的策略,抓取所需要的内容
实例代码如下:
代码语言:javascript代码运行次数:0运行复制import requests,re
# import time
# from collections import Counter
count = 20
r = re.compile(r'href=[\'"]?(http[^\'">]+)')
seed = 'https://www.baidu.com/more/'
queue = [seed]
used = set() # 设置一个集合,保存已经抓取过的URL
storage = {}
while len(queue) > 0 and count > 0 :
try:
url = queue.pop(0)
html = requests.get(url).text
storage[url] = html #将已经抓取过的URL存入used集合中
used.add(url)
new_urls = r.findall(html) # 将新发行未抓取的URL添加到queue中
print(url+"下的url数量为:"+str(len(new_urls)))
for new_url in new_urls:
if new_url not in used and new_url not in queue:
queue.append(new_url)
count -= 1
except Exception as e :
print(url)
print(e)我们可以感受下一个一级网页到下一级网页的链接能有多么多
一、抓取策略从网络爬虫的角度来看,整个互联网可以划分为:
在网络爬虫的组成部分中,待抓取URL队列是最重要一环待抓取队列中的URL以什么样的顺序排列,这涉及到页面抓取的先后问题决定待抓取URL排列顺序的方法,成为抓取策略网络爬虫使用不同的抓取策略,实质是使用不同的方法确定待抓取URL队列中URL的先后顺序爬虫的多种抓取策略目标基本一致:优先抓取重要的网页网页的重要想,大多数采用网页的流动性来进行度量1、数据抓取策略非完全PageRank策略OCIP策略大站优先策略合作抓取策略图遍历算法策略1.1、非完全PageRank策略 PageRank算法,是一种著名的超链接分析算法,用来进行网页排名,以谷歌创始人Larry Page命名
PageRank策略算法基于以下的思想对网页的重要性进行评分:
①一个网页被很多其他网页链接,该网页比较重要,PageRank分数回相对较高
② 一个PageRank分数高的网页链接到一个其他的网页,被链接到的网页的PageRank分数会相应提高
通常来讲,一个网页的PageRank分数计算如下:
PageRank算法计算的对象是整个互联网页面的集合;而非完全PageRank策略则关注的是以下的页面集合:
①网络爬虫已经下载的页面
②待抓取URL队列的URL之后由两者组成的页面子集中,计算PageRank分数根据PageRank分数,按照从高到低的顺序,将待抓取URL队列重排,形成新的待抓取URL队列1.2、OPIC策略OPIC,是Online Page Importance Computation的缩写,是一种改进的PageRank算法
OPIC策略的基本思想
将互联网的页面初始cash值设为1/N每当网络爬虫下载页面a,将a的cash值平均分配给页面中包含的链接,再将自己的cash值设为零将待抓取URL队列中的URL按照cash值进行降序排列,优先处理cash值高的网页1.3、大站优先策略(比较粗暴)大站优先策略的思路简单明了:
依据网站决定网页重要性,对于待爬取URL队列中的网页根据所属网站归类等待下载的页面最多的网站,会得到网络爬虫的“优先考虑”“大战”通常具有以下特点:
稳定的服务器,良好的网站结构优秀的用户体验,及时的咨询内容权威的相关资料,丰富的内容类型海量的网页数,高质量的外链如何识别要抓取的目标网站是否为大战?
人工整理大站名单,通过已知的大站发现其他大站根据大站的特点,对将要爬取的网站进行评估(架构,内容,传播速度等)1.4、合作抓取策略(需要一个规范的URL地址)为了提高抓取网页的速度,常见的选择是增加网络爬虫的数量
如何给这些爬虫分配不同的工作量,确保独立分工,避免重复爬取,这是合作抓取策略的目标
合作抓取策略通常使用以下两种方式:
通过服务器的IP地址来分解,让爬虫仅抓取某个地址段的网页通过网页域名来分解,让爬虫仅抓取某个域名段的网页1.5、图的遍历算法策略图的遍历算法主要分成两种:
深度优先(DFS,Depth First Search)广度优先(BFS,Breadth First Search)1、深度优先深度优先从根节点开始,沿着一条路径尽可能深地访问,直到遇到叶节点时才回溯
深度优先由自己的优点,但更容易陷入无限循环2、广度优先使用广度优先策略的原因:
重要的网页往往离种子站点距离较近互联网的深度没有那么深,但却出乎意料地宽广广度优先遍历策略地基本思路
将新下载网页中发现的链接直接插入待抓取URL队列的末尾。也就是指网络爬虫会先抓取起始网页中链接的所有网页再选择其中一个链接网页,继续抓取在此网页中链接的所有网页广度优先策略从根节点开始,尽可能访问离根节点最近的节点
3、代码实现用list模拟队列,实现BFS算法:
代码语言:javascript代码运行次数:0运行复制import requests,re
count = 20
r = re.compile(r'href=[\'"]?(http[^\'">]+)')
seed = 'http://httpbin.org/'
queue = [seed]
storage = {}
while len(queue) > 0 and count > 0 :
try:
url = queue.pop(0)
html = requests.get(url).text
storage[url] = html #将已经抓取过的URL存入used集合中
used.add(url)
new_urls = r.findall(html) # 将新发行未抓取的URL添加到queue中
print(url+"下的url数量为:"+str(len(new_urls)))
for new_url in new_urls:
if new_url not in used and new_url not in queue:
queue.append(new_url)
count -= 1
except Exception as e :
print(url)
print(e)
用list模拟队列,实现DFS算法:
代码语言:javascript代码运行次数:0运行复制import requests,re
count = 20
r = re.compile(r'href=[\'"]?(http[^\'">]+)')
seed = 'http://httpbin.org/'
queue = [seed]
storage = {}
while len(stack) > 0 and count > 0 :
try:
url = stack.pop(-1)
html = requests.get(url).text
new_urls = r.findall(html)
stack.extend(new_urls)
print(url+"下的url数量为:"+str(len(new_urls)))
storage[url] = len(new_urls)
count -= 1
except Exception as e :
print(url)
print(e)统计:
真的会陷入无限循环吗?
我们发现其中包含了一些重复的URL重复时因为网页的链接形成一个闭环要标记已经抓取过的URL,防止浪费无谓的资源2、数据更新策略抓取策略关注待抓取URL队列,也就是互联网中的待下载页面的合集针对已下载的网页来说,互联网实时变化,页面随时会有变化更新策略决定何时更新之前已经下载过的页面常见的更新策略有以下几种:
历史参考策略:根据页面历史数据,预测页面的变化用户体验策略:总和用户的浏览偏好,更新用户关注度高的网页聚类抽样策略:根据页面的类别,确定页面的更新周期聚类策略的基本思路
二、爬虫持久化持久化方法:
依赖URL管理的数据结构依赖爬虫爬取策略依赖爬虫的更新策略依赖临时存储和永久存储