python爬虫爬取策略

爬取策略

关注公众号“轻松学编程”了解更多。

在爬虫系统中,待抓取URL队列是很重要的一部分。待抓取URL队列中的URL以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面。而决定这些URL排列顺序的方法,叫做抓取策略。下面重点介绍几种常见的抓取策略:

一、深度优先遍历策略

深度优先遍历策略是指网络爬虫会从起始页开始,一个链接一个链接跟踪下去,处理完这条线路之后再转入下一个起始页,继续跟踪链接。我们以下面的图为例:遍历的路径:A-F-G E-H-I B C D

1、递归实现流程

a.获取种子链接 b.设置爬取深度 c.判断是否超出深度 d.爬取数据 e.生成子类url链接池 f.遍历子链接池,去重 g.深度加1,递归

import re
import requests

# 设置请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; 
    Win64; x64) AppleWebKit/537.36 (KHTML,
     like Gecko) Chrome/65.0.3325.181 Safari/537.36"}

def getHtml(url):
    '''
    获取html源码
    :param url:
    :return:
    '''
    response = requests.get(url,headers=headers)
    return response.content.decode("utf-8",errors="ignore")

def getUrl(url):
    '''
    获取新url
    :param url:链接
    :return: urllist
    '''
    # 获取html
    html = getHtml(url)
    # print(html)
    # 清洗出新的url
    '''
    <a class="title-content" href="https://www.baidu.com/s?
    cl=3&ap;rsv_idx=2" target="_blank">世界杯八强出炉</a>
    '''
    urlre = '<a .*href="(https?://.*?)".*'
    urlList = re.findall(urlre,html)
    print(urlList)
    return urlList

def getInfo(url):
    '''
    爬取数据
    :param url:
    :return:
    '''
    pass

def depthSpider(url,depth):
    '''
    递归实现深度爬取数据
    :param url: url链接
    :param depth: 爬取深度限制
    :return:
    '''
    # 判断是否超出深度,超出就结束
    if depthDict[url] > depth:
        return
    print("\t"*depthDict[url], "抓取第%d层:%s"
    %(depthDict[url], url))
    # 要实现的爬虫,爬取数据
    # getInfo(url)

    #生成子类url链接池
    sonUrlList = getUrl(url)

    #遍历子链接池
    for newurl in sonUrlList:
        #去重
        if newurl not in depthDict:
            #层级加1
            depthDict[newurl] = depthDict[url]+1
            #递归
            depthSpider(newurl,depth)

if __name__ == '__main__':
    # 种子链接
    startUrl = "https://www.baidu.com/s?wd=世界杯"
    #设置爬取深度,设置爬取深度为4
    depthLimit = 2
    depthDict = {}
    depthDict[startUrl] = 1
    # 深度抓取
    depthSpider(startUrl,depthLimit)
2、栈实现流程

a.获取种子链接 b.用栈实现深度,设置爬取深度 c.判断栈是否为空 d.从栈中拿出一个url e.判断是否超出深度 f.爬取数据 g.生成子类url链接池 h.遍历子链接池,去重 i.深度加1,添加到栈中

import requests
import re

# 设置请求头
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; 
    Win64; x64) AppleWebKit/537.36 (KHTML,
     like Gecko) Chrome/65.0.3325.181 Safari/537.36"}

def getHtml(url):
    '''
    获取html源码
    :param url:
    :return:
    '''
    response = requests.get(url,headers=header)
    return response.content.decode("utf-8",errors="ignore")

def getUrl(url):
    '''
    生成url链接池
    :param url: 链接
    :return: 列表
    '''
    # 获取html源码
    html = getHtml(url)
    # print(html)
    # 清洗出新的url
    '''
    <a class="title-content" href="https://www.baidu.com/s?
    cl=3&ap;rsv_idx=2" target="_blank">世界杯八强出炉</a>
    '''
    urlre = '<a .*href="(https?://.*?)".*'
    urlsList = re.findall(urlre,html)
    return urlsList

def getInfo(url):
    '''
    爬取数据
    :param url:
    :return:
    '''
    pass

def stackSpider(depth):
    '''
    栈实现深度爬取数据
    :param depth: 深度
    :return:
    '''
    while len(urlList) > 0:
        # 从栈中取出一个url,先进后出
        url = urlList.pop()
        if depthDict[url] <= depth:
            print("\t\t\t" * depthDict[url], 
            "抓取了第%d层:%s" % (depthDict[url], url))

            # 要实现的爬虫,爬取数据
            # getInfo(url)
            # 生成子类url链接池
            sonUrlLisr = getUrl(url)
            # 遍历子类url链接池
            for newurl in sonUrlLisr:
                if newurl not in depthDict:
                    depthDict[newurl] = depthDict[url] +1
                    #深度加1,添加到栈中
                    urlList.append(newurl)

if __name__ == '__main__':
    #设置种子链接
    startUrl = "https://www.baidu.com/s?wd=世界杯"
    #用队列实现广度
    urlList = []
    urlList.append(startUrl)
    # 设置爬取深度,设置爬取深度为4
    depthLimit = 3
    depthDict = {}
    depthDict[startUrl] = 1
    # 广度爬取
    stackSpider(depthLimit)

二、广度优先遍历策略

广度优先遍历策略的基本思路是,将新下载网页中发现的链接直接追加到待抓取URL队列的末尾。也就是指网络爬虫会先抓取起始网页中链接的所有网页,然后再选择其中的一个链接网页,继续抓取在此网页中链接的所有网页。还是以上面的图为例:遍历路径:A-B-C-D-E-F-G-H-I

1、队列实现流程

a.获取种子链接 b.用队列实现广度,设置爬取深度 c.判断队列是否为空 d.从队列拿出一个url e.判断是否超出深度 f.爬取数据 g.生成子类url链接池 h.遍历子链接池,去重 i.深度加1,添加到队列中

'''
a.获取种子链接 b.用队列实现广度,设置爬取深度 c.判断队列是否为空 
d.从队列拿出一个url e.判断是否超出深度 f.爬取数据 
g.生成子类url链接池 h.遍历子链接池,去重  i.深度加1,添加到队列中
'''
import requests
import re

# 设置请求头
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0;
     Win64; x64) AppleWebKit/537.36 (KHTML, 
     like Gecko) Chrome/65.0.3325.181 Safari/537.36"}

def getHtml(url):
    '''
    获取html源码
    :param url:
    :return:
    '''
    response = requests.get(url,headers=header)
    return response.content.decode("utf-8",errors="ignore")

def getUrl(url):
    '''
    生成url链接池
    :param url: 链接
    :return: 列表
    '''
    # 获取html源码
    html = getHtml(url)
    # print(html)
    # 清洗出新的url
    '''
    <a class="title-content" href="https://www.baidu.com/s?
    cl=3&ap;rsv_idx=2" target="_blank">世界杯八强出炉</a>
    '''
    urlre = '<a .*href="(https?://.*?)".*'
    urlsList = re.findall(urlre,html)
    return urlsList

def getInfo(url):
    '''
    爬取数据
    :param url:
    :return:
    '''
    pass

def vastSpider(depth):
    '''
    队列实现广度爬取数据
    :param depth: 深度
    :return:
    '''
    while len(urlList) > 0:
        # 从队列中取出一个url
        url = urlList.pop(0)
        if depthDict[url] <= depth:
            print("\t\t\t" * depthDict[url],
             "抓取了第%d层:%s" % (depthDict[url], url))

            # 要实现的爬虫,爬取数据
            # getInfo(url)
            # 生成子类url链接池
            sonUrlLisr = getUrl(url)
            # 遍历子类url链接池
            for newurl in sonUrlLisr:
                #去重
                if newurl not in depthDict:
                    depthDict[newurl] = depthDict[url] +1
                    #深度加1,添加到队列中
                    urlList.append(newurl)

if __name__ == '__main__':
    #设置种子链接
    startUrl = "https://www.baidu.com/s?wd=世界杯"
    #用队列实现广度
    urlList = []
    urlList.append(startUrl)
    # 设置爬取深度,设置爬取深度为4
    depthLimit = 2
    depthDict = {}
    depthDict[startUrl] = 1
    # 广度爬取
    vastSpider(depthLimit)

后记

【后记】为了让大家能够轻松学编程,我创建了一个公众号【轻松学编程】,里面有让你快速学会编程的文章,当然也有一些干货提高你的编程水平,也有一些编程项目适合做一些课程设计等课题。

也可加我微信【1257309054】,拉你进群,大家一起交流学习。
如果文章对您有帮助,请我喝杯咖啡吧!

公众号

公众号

赞赏码

关注我,我们一起成长~~

posted @ 2018-07-05 20:01  轻松学编程  阅读(449)  评论(0编辑  收藏  举报