1. 程式人生 > >Python爬蟲學習(3)

Python爬蟲學習(3)

collect nbsp pri div time urlparse links ews 是否

在慕課網學習並創建了一個簡單的爬蟲包,爬取百度百科相關詞條信息

程序中會用到第三方解析包(BeautifulSoup4),Windows環境下安裝命令:pip install BeautifulSoup4

1、新建包

技術分享圖片技術分享圖片

2、新建相關類文件,其中包含有:

  index.py,包入口類文件;

  url_manager.py,url管理器類文件,主要管理待爬url列表和已爬url列表,避免重復或循環爬取;

  html_downloader.py,html內容下載器類文件,下載接收url內容到本地;

  html_parser.py,html內容解析器類文件,解析url內容,取出需求數據;

  html_outputer.py,爬取內容收集輸出器類文件,主要收集各url中需求數據並輸出;

技術分享圖片

3、貼(代碼註釋好詳細的。。。)

index.py

# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# addUser: Gao
# addTime: 2018-01-31 22:22
# description: 入口

from Crawler import url_manager, html_downloader, html_parser, html_outputer


class Index(object):

    # 構造函數 初始化各管理器
    def __init__(self):
        # url管理器
        self.urls = url_manager.UrlManager()
        # html下載管理器
        self.downloader = html_downloader.HtmlDownloader()
        # html解析管理器
        self.parser = html_parser.HtmlParser()
        # 數據收集管理器
        self.outputer = html_outputer.HtmlOutputer()

    # 爬蟲
    def craw(self, url):
        count = 1

        # 將初始地址加入url管理器
        self.urls.add_new_url(url)

        # 判斷是否存在新的url地址 存在時執行爬取程序
        while self.urls.has_new_url():
            try:
                # 獲取新的url地址
                new_url = self.urls.get_new_url()
                print ‘craw %d : %s‘ % (count, new_url)

                # 獲取url地址內容
                html_cont = self.downloader.download(new_url)

                # 解析url內容
                news_url, new_data = self.parser.parse(new_url, html_cont)

                # 將解析得到的url地址列表批量加入url管理器中
                self.urls.add_new_urls(news_url)

                # 收集數據
                self.outputer.collect_data(new_data)

                if count == 100:
                    break
                count += 1

            # 異常處理
            except:
                print ‘craw failed‘

        # 輸出收集的數據
        self.outputer.output_html()


if __name__ == ‘__main__‘:
    # 初始url地址
    initial_url = ‘https://baike.baidu.com/item/%E5%94%90%E8%AF%97%E4%B8%89%E7%99%BE%E9%A6%96/18677‘

    # 創建對象
    Obj = Index()

    # 調用爬蟲
    Obj.craw(initial_url)

url_manager.py

# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# addUser: Gao
# addTime: 2018-01-31 22:22
# description: url管理器


class UrlManager(object):
    # 構造函數 初始化url列表
    def __init__(self):
        # 待爬url列表
        self.new_urls = set()
        # 已爬url列表
        self.old_urls = set()

    # 添加單個url
    def add_new_url(self, url):
        # 判斷url是否為空
        if url is None:
            return
        # 判斷url是否已存在或是否已爬
        if url not in self.new_urls and url not in self.old_urls:
            # 添加到待爬url列表
            self.new_urls.add(url)

    # 批量添加url
    def add_new_urls(self, urls):
        # 判斷urls是否為空
        if urls is None or len(urls)==0:
            return
        # 循環執行添加單個url
        for url in urls:
            self.add_new_url(url)

    # 判斷是否存在新的(未爬取)url
    def has_new_url(self):
        return len(self.new_urls) != 0

    # 獲取新的(未爬取)url
    def get_new_url(self):
        # 取出待爬url列表中的一個url
        new_url = self.new_urls.pop()
        # 將取出的url添加到已爬url列表中
        self.old_urls.add(new_url)
        # 返回取出的url
        return new_url

html_downloader.py

# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# addUser: Gao
# addTime: 2018-01-31 22:22
# description: html下載器

import urllib2


class HtmlDownloader(object):

    # 下載url內容
    def download(self, url):
        # 判斷url是否為空
        if url is None:
            return None

        # 下載url內容
        response = urllib2.urlopen(url)
        # 判斷url地址請求結果
        if response.getcode() != 200:
            return None
        # 返回url加載內容
        return response.read()

html_parser.py

# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# addUser: Gao
# addTime: 2018-01-31 22:22
# description: html解析器

import re, urlparse
from bs4 import BeautifulSoup


class HtmlParser(object):

    # 解析url的內容
    def parse(self, url, html_cont):
        # 參數為空判斷
        if url is None or html_cont is None:
            return

        # 創建解析對象
        soup = BeautifulSoup(html_cont, ‘html.parser‘, from_encoding=‘utf-8‘)
        # 獲取新的待爬url列表
        new_urls = self._get_new_urls(url, soup)
        # 獲取需求數據
        new_data = self._get_new_data(url, soup)
        # 返回url列表和數據
        return new_urls, new_data

    # 獲取url內容中的詞條url列表
    def _get_new_urls(self, url, soup):
        # 初始化url列表
        new_urls = set()

        # 獲取頁面所有詞條a標簽列表
        links = soup.find_all(‘a‘, href=re.compile(r‘^/item/‘))
        for link in links:
            new_url = link[‘href‘]  # 獲取a標簽中href屬性值
            full_url = urlparse.urljoin(url, new_url)   # 拼接完整url地址
            new_urls.add(full_url)  # 將完整的url添加到url列表中

        # 返回url列表
        return new_urls

    # 獲取url內容中的需求數據
    def _get_new_data(self, url, soup):
        # 初始化數據詞典
        data = {}

        title_node = soup.find(‘dd‘, class_=‘lemmaWgt-lemmaTitle-title‘).find(‘h1‘)     # 獲取標題標簽
        data[‘title‘] = title_node.get_text()   # 獲取標題文本

        summary_node = soup.find(‘div‘, class_=‘lemma-summary‘)     # 獲取詞條概要標簽
        data[‘summary‘] = summary_node.get_text()   # 獲取詞條概要文本

        data[‘url‘] = url  # 詞條對應url地址

        # 返回數據
        return data

html_outputer.py

# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# addUser: Gao
# addTime: 2018-01-31 22:22
# description: html輸出器


class HtmlOutputer(object):

    # 構造函數 初始化收集的數據
    def __init__(self):
        self.Data = []

    # 收集數據
    def collect_data(self, data):
        # 數據為空判斷
        if data is None:
            return
        # 添加數據到列表
        self.Data.append(data)

    # 輸出收集的數據
    def output_html(self):
        # 打開文件
        out_file = open(‘output.html‘, ‘w‘)

        out_file.write(‘<html><body><table>‘)

        for data in self.Data:
            out_file.write(‘<tr>‘)
            out_file.write(‘<td>%s</td>‘ % data[‘title‘].encode(‘utf-8‘))
            out_file.write(‘<td>%s</td>‘ % data[‘url‘].encode(‘utf-8‘))
            out_file.write(‘<td>%s</td>‘ % data[‘summary‘].encode(‘utf-8‘))
            out_file.write(‘</tr>‘)

        out_file.write(‘</table></body></html>‘)

        # 關閉文件
        out_file.close()

4、運行和調用

  代碼擼完了,肯定要看看它是否能使用啦

  在包中,選擇入口類文件(index.py),右擊執行Run命令;

  在包外,即調用該爬蟲包,首先要引入該包入口類文件(index.py),再實例化對象,最後調用爬取方法,當然還得執行Run命令啦。

  技術分享圖片

我的代碼:https://github.com/HeyEasy/PythonCode

Python爬蟲學習(3)