<wbr id="juant"></wbr>
  • <wbr id="juant"></wbr>
    更多課程 選擇中心


    Python培訓

    400-111-8989

    Python3 開發輕量級爬蟲教程

    • 發布:Python培訓
    • 來源:Python練習題庫
    • 時間:2018-02-27 11:58

    爬蟲又被稱為網頁蜘蛛,網絡機器人。是一種按照一定的規則,自動地抓取互聯網上信息的程序或者腳本。

    一、爬蟲算法

    在寫爬蟲時候有兩種常用的算法可使用,即深度優先算法、廣度優先算法。

    深度優先算法

    對每一個可能的分支路徑深入到不能再深入為止,而且每個結點只能訪問一次。直到訪問完成后再返回到最上層,然后重復上述步驟。

    廣度優先算法

    從上往下對每一層依次訪問,在每一層中,從左往右(也可以從右往左)訪問結點,訪問完一層就進入下一層,直到沒有結點可以訪問為止。

    負載均衡

    當爬取量很大的話,需要負載到多臺服務器同時運行(搜索引擎都是這么做的)。但這樣會出現一個問題,當 A 服務器已經爬取完成的 URL,但 B 服務器并不知道 A 是否爬取完成,這樣會造成資源的浪費,那怎么辦呢?如何突破爬蟲的瓶頸?

    其中最簡單的便是 URL 分類。舉個栗子:現在有 A、B、C、D、X 五臺服務器同時運行爬蟲,X 為負載均衡服務器。所有的 URL 都要經過 X 服務器進行分配, X 服務器遇到域名是 .com 結尾的就分配給 A,遇到 .cn 結尾就分配給 B,遇到 .net 結尾就分配給 C,其他域名都分配給 D。這樣就解決了爬蟲瓶頸的問題,這個問題可是谷歌的面試題。

    二、爬蟲邏輯

    爬蟲可大致分為五個部分:

    • 調度器:引擎,是爬蟲邏輯實現的模塊

    • 管理器:URL 管理器,負責新增、刪除、獲取、存儲、計數等功能,避免爬取重復的 URL。

    • 下載器:HTML 下載器,將 URL 地址中的 HTML 內容獲取到

    • 解析器:HTML 解析器,將 HTML 獲取到的內容進行分析

    • 輸出器:將分析完成后的數據進行輸出、存儲、利用等

    爬蟲邏輯可分解為如下幾個部分:

    1. 查詢管理器中是否有待爬取的 URL

    2. 調度器從管理器中獲取一個待爬取 URL

    3. 將獲取到的 URL 交給下載器處理

    4. 將下載器獲取到的網頁數據交給解析器處理

    5. 將解析器處理后的 URL 集合交給管理器

    6. 將解析器處理后的數據交給輸出器

    7. 重復上述步驟

    三、開發輕量級爬蟲

    1. 調度器

    spider.py

    #!/usr/bin/env python3
    # -*- coding: UTF-8 -*-
    
    #
    # 【調度器】
    #
    # 調度器又稱為引擎,是爬蟲邏輯實現的模塊。
    #
    # 爬蟲邏輯可分解為如下幾個部分:
    #
    # 1. 查詢管理器中是否有待爬取的 URL
    # 2. 調度器從管理器中獲取一個待爬取 URL
    # 3. 將獲取到的 URL 交給下載器處理
    # 4. 將下載器獲取到的網頁數據交給解析器處理
    # 5. 將解析器處理后的 URL 集合交給管理器
    # 6. 將解析器處理后的數據交給輸出器
    # 7. 重復上述步驟
    # 
    
    
    import manager, download, parser, output
    
    
    class Spider(object):
    
        def __init__(self):
    
            # 實例化 管理器、下載器、解析器、輸出器
            self.manager  = manager.Manager()
            self.download = download.Download()
            self.parser   = parser.Parser()
            self.output   = output.Output()
    
        def spider(self, url):
    
            # 爬蟲計數器
            count = 0
    
            # 將第一個 URL 放入管理器中
            self.manager.add_url(url)
    
            # 判斷管理器中 URL 的數量是否為 0
            while self.manager.num_url():
    
                try:
    
                    # 從管理器中獲取一個 URL
                    new_url = self.manager.get_url()
    
                    # 將獲取到的 URL 交給下載器處理
                    html_cont = self.download.download(new_url)
    
                    # 將 URL 和 下載器處理后的網頁數據交給解析器處理
                    new_manager, new_data = self.parser.parser(new_url, html_cont)
    
                    # 將解析器處理后的數據和新的 URL 分別交給管理器和輸出器
                    self.manager.add_urls(new_manager)
                    self.output.add_data(new_data)
    
                    # 最多爬取 100 次
                    if count == 100:
                        break
    
                    count += 1
    
                    print('爬蟲運行狀態 ==> %d : %s' % (count, new_url))
    
                except:
    
                    print('爬蟲爬取失敗')
    
            # 當爬蟲爬取完所有數據后,輸出器將數據輸出到文件
            self.output.output()
    
    if __name__ == '__main__':
    
        # URL 入口(爬蟲爬取的第一個 URL)
        url = 'http://www.cnblogs.com/peida/archive/2012/12/05/2803591.html'
    
        # 實例化調度器并啟動爬蟲
        run = Spider()
        run.spider(url)

    2. 管理器

    manager.py

    #!/usr/bin/env python3
    # -*- coding: UTF-8 -*-
    
    #
    # 【管理器】
    #
    # 對外提供四個方法:
    #
    # 1. add_url(url)
    # 添加一個 URL,接收一個參數 URL
    # 
    # 2. add_urls(url)
    # 批量添加 URL,接收一個參數 URL
    #
    # 3. num_url()
    # 管理器中URL 的數量
    # 
    # 4. get_url()
    # 從管理器中獲取一個 URL
    #
    
    
    class Manager(object):
    
        def __init__(self):
    
            # 待爬取的 URL 集合
            self.new_urls = set()
            # 已爬取的 URL 集合
            self.old_urls = set()
    
        # 添加一個 URL
        def add_url(self, url):
    
            # 判斷 url 是否為空,為空則返回 None
            if url is None:
                return
    
            # 判斷 url 是否存在于【待爬取的 URL 集合】和【已爬取的 URL 集合】,如若都不在將新 url 添加到【待爬取的 URL 集合】中
            if url not in self.new_urls and url not in self.old_urls:
                self.new_urls.add(url)
    
        # 批量添加 URL
        def add_urls(self, urls):
    
            if urls is None or len(urls) == 0:
                return
    
            for url in urls:
                # 將 URL 集合交給 add_url() 函數處理
                self.add_url(url)
    
        # 返回管理器中 URL 的數量
        def num_url(self):
    
            return len(self.new_urls) != 0
    
        # 從管理器中獲取一個 URL
        def get_url(self):
    
            url = self.new_urls.pop()
            self.old_urls.add(url)
    
            return url

    3. 下載器

    download.py

    #!/usr/bin/env python3
    # -*- coding: UTF-8 -*-
    
    #
    # 【下載器】
    #
    # requests 模塊需要安裝
    # sudo pip3 install requests
    #
    # 對外提供一個方法:
    #
    # download(url)
    # 下載網頁中的內容,接收一個參數 URL
    #
    
    
    import requests
    
    
    class Download(object):
    
        def download(self, url):
    
            # 判斷 URL 是否為空,為空直接返回 None
            if url is None:
                return None
    
            # 請求 URL
            response = requests.get(url = url)
    
            # 判斷 URL 地址是否訪問成功,若失敗直接返回 None
            if response.status_code != 200:
                return None
    
            return response.text

    4. 解析器

    parser.py

    #!/usr/bin/env python3
    # -*- coding: UTF-8 -*-
    
    #
    # 【解析器】
    #
    # bs4 模塊需要安裝
    # sudo pip3 install bs4
    #
    # 對外提供一個方法:
    #
    # 1. parser(url)
    # BeautifulSoup DOM 樹處理,接收兩個參數 URL 和 html 內容
    #
    # 對內提供兩個方法:
    #
    # 1. _get_urls(url, soup)
    # 獲取網頁中的 URL,接收兩個參數 URL 和 DOM 樹
    #
    # 2. _get_data(url, soup)
    # 獲取網頁中的數據,接收兩個參數 URL 和 DOM 樹
    #
    
    
    import re
    from bs4 import BeautifulSoup
    
    
    class Parser(object):
    
        def _get_urls(self, url, soup):
    
            urls = set()
    
            links = soup.find_all('a', href=re.compile(r'/peida/archive/*'))
    
            for link in links:
    
                new_url = link['href']
                urls.add(new_url)
    
            return urls
    
        def _get_data(self, url, soup):
    
            res_data = {}
            res_data['url'] = url
            title_node = soup.find('div', class_='post').find('a')
            res_data['title'] = title_node.get_text()
    
            return res_data
    
        def parser(self, url, html):
    
            # 判斷 url 是否為空,或網頁數據是否為空,為空則返回 None
            if url is None or html is None:
                return
    
            # 格式化 html 為 BeautifulSoup DOM 樹
            soup = BeautifulSoup(html, 'html.parser')
    
            # 獲取網頁中的 URL
            urls = self._get_urls(url, soup)
            # 獲取網頁中的數據
            data = self._get_data(url, soup)
    
            return urls, data

    5. 輸出器

    output.py

    #!/usr/bin/env python3
    # -*- coding: UTF-8 -*-
    
    #
    # 【輸出器】
    #
    # 對外提供兩個方法:
    #
    # 1. add_data(data) 
    # 存儲網頁數據,接收一個參數 data
    # 
    # 2. output()
    # 將數據輸出到 html 文件中
    #
    
    
    class Output(object):
    
        def __init__(self):
    
            self.datas = []
    
        def add_data(self, data):
    
            if data is None:
                return 
    
            self.datas.append(data)
    
        def output(self):
    
            head = '''
    
                <html>
                <meta charset="UTF-8">
                <body>
                <table>
    
            '''
    
            foot = '''
    
                </table>
                </body>
                </html>
    
            '''
    
            with open('CSDN.html', 'w') as f:
    
                f.write(head)
    
                for data in self.datas:
    
                    f.write('<tr><td><a href =%s>%s</a></td>' % (data['url'], data['url']))
                    f.write('<td>%s</td></tr>' % data['title'])
    
                f.write(foot)

    運行結果:

    預約申請免費試聽課

    填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

    上一篇:如何讓你的python代碼更高效靈活
    下一篇:使用 Python 標準庫上傳文件

    2021年Python面試題及答案匯總詳解

    python數據分析,你需要這些工具

    Python培訓講解二叉樹的三種深度

    Python培訓:如何實現窮舉搜索?

    • 掃碼領取資料

      回復關鍵字:視頻資料

      免費領取 達內課程視頻學習資料

    • 視頻學習QQ群

      添加QQ群:1143617948

      免費領取達內課程視頻學習資料

    Copyright ? 2021 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

    選擇城市和中心
    黑龍江省

    吉林省

    河北省

    湖南省

    貴州省

    云南省

    廣西省

    海南省

    天天日天天射天天干天天伊|奇米电影|奇米网_奇米首页|奇米首页 百度 好搜 搜狗
    <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>