• 百度AI搜索引擎


    一、爬虫协议

      与其它爬虫不同,全站爬虫意图爬取网站所有页面,由于爬虫对网页的爬取速度比人工浏览快几百倍,对网站服务器来说压力山大,很容易造成网站崩溃。 为了避免双输的场面,大家约定,如果网站建设者不愿意爬虫访问某些页面,他就按照约定的格式,把这些页面添加到 robots.txt 文件中,爬虫应该主动避免访问这些页面。除此之外,作为爬虫编写者也应该主动控制爬虫访问速度。

      访问 robots 协议的方式是:网站域名+'/robots.txt'。

    二、处理爬虫协议

    import urllib.robotparser
    
    url = 'https://ai.baidu.com'
    rp = urllib.robotparser.RobotFileParser()
    rp.set_url(url + '/robots.txt')
    rp.read()
    info = rp.can_fetch("*", 'https://ai.baidu.com/product/minos')
    print(info)

     三、全站爬虫的基本架构

      爬虫从一个 URL 开始访问,通常是网站的域名,并将获得网页中的链接提取出来,去重后放入待访问列表。重复此操作,知道访问完网站内全部网页。

      需要注意的是,全站爬虫通常只爬取网站的内部链接

    四、网页链接提取

    from requests_html import HTMLSession
    session = HTMLSession()
    origin = 'https://ai.baidu.com'
    r = session.get(origin)
    print(r.html.links)

    五、链接过滤

      使用 urllib 库过滤所有非内部链接,继续运行下面的代码,观察结果:

    from urllib.parse import urlparse
    from requests_html import HTMLSession
    session = HTMLSession()
    origin = 'https://ai.baidu.com'
    r = session.get(origin)
    print(r.html.links)
    
    domain = 'ai.baidu.com'
    
    def is_inner_link(link):
        netloc = urlparse(link).netloc
        return (not netloc) or (netloc == domain)
        
    for link in r.html.links:
        print(is_inner_link(link), link)

       除了过滤非内部链接外,还需要把已经访问过的链接、爬虫协议不允许的链接 和 你不想访问的链接都过滤掉。

    六、百度AI爬虫实现

    from requests_html import HTMLSession
    import urllib.robotparser
    from urllib.parse import urlparse
    
    session=HTMLSession()
    origin= 'https://www.xuexi.cn/'
    domain=urlparse(origin).netloc
    
    
    def is_inner_link(link):
        netloc=urlparse(link).netloc
        return (not netloc) or (netloc==domain)
    
    visited = []  # 已访问链接列表
    unvisited = [origin]  # 待访问链接列表
    
    # 解析爬虫协议
    rp = urllib.robotparser.RobotFileParser()
    rp.set_url(origin + '/robots.txt')
    rp.read()
    
    def add_unvisited(link):
        # 过滤1:判断爬虫协议是否允许
        allow = rp.can_fetch('*', link)
        if not allow:
            return
    
        # 过滤2:判断是否为内链
        if not is_inner_link(link):
            return
    
        # 过滤3:去掉非法链接
        path = urlparse(link).path
        if not path.startswith('/'):
            return
    
        # 过滤4:自定义过滤
        if urlparse(link).path.startswith(('/file', '/docs', '/support', '/forum', '/broad', '/paddlepaddle', '/market',
                                           '/download', '/facekit', '/sdk', '/customer', '/easydl', '//')):
            return
    
        # 将 /tech/123 转换为 https://ai.baidu.com/tech/123 的形式
        if link.startswith('/'):
            link = origin + link
    
        # 过滤5:判断是否访问过,或已经添加到待访问列表
        if (link in visited) or (link in unvisited):
            return
    
        unvisited.append(link)
    
    while len(unvisited):
        link=unvisited.pop()    #用于移除列表中的一个元素
        r=session.get(link)
        visited.append(link)
        if r.html and r.html.links and len(r.html.links):
            for url in r.html.links:
                add_unvisited(url)
    
        if r.html.find('head title')[0]:
            print(r.html.find('head title')[0].text,link)
    
    print('共爬取{}个链接'.format(len(visited)))
  • 相关阅读:
    2017 ACM/ICPC Asia Regional Qingdao Online
    2017 ACM/ICPC Asia Regional Qingdao Online
    2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Sum
    2017 ACM/ICPC Asia Regional Shenyang Online array array array
    无权最短路
    解题报告:poj 3070
    矩阵学习笔记
    拓扑排序
    LIS严格递增和非递减模板
    2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-A banana·
  • 原文地址:https://www.cnblogs.com/start20180703/p/10396504.html
Copyright © 2020-2023  润新知