iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0
自我挑戰組

Python 30天自我挑戰系列 第 16

Day16 - 完成爬蟲功能

在完成基礎的表單畫面後,接著需要將之前完成的爬蟲功能整合至網站。

考量功能的獨立性、擴充性和使用便利性,這次預計將爬蟲功能打包成一個套件,今天的實作內容則為套件開發。

架構

  1. bookcrawler.py:提供使用者建立爬蟲物件。

  2. plugin:放置plugin的資料夾。

    • wwwjjwxc_bookcrawler.py:實作www.jjwxc.net的方法。

https://ithelp.ithome.com.tw/upload/images/20210928/20141886mrYWZsGD6d.png

bookcrawler.py

宣告BookCrawler類別,作為使用者可以建立的物件。

  • init(self, url): 建立物件時需由使用者輸入URL,物件初始化流程包含:

    1. 屬性的初始化

    2. URL大小寫轉換,確保資料品質

    3. URL解析,取得網域

    4. 根據網域選擇合適的plugin

  • getinfo():任務為執行對應plugin中的實際的getinfo(),並將plugin中取得的網站資訊寫進主體。

import re
from crawler.plugin.wwwjjwxc_bookcrawler import wwwjjwxc_BookCrawler

class BookCrawler:
  def __init__(self, url):
    self.authorname = None
    self.title = None
    self.totalsection = 0
    self.url = url.lower()
    regex = r'(https?:\/\/)([\da-z\.-]+\.[a-z\.]{2,6})([\/\w \.-]*)*\/'
    self.domain = re.search(regex, self.url).group(2)

    # 依網域選擇plugin
    ### 暫時先hardcode ###
    if self.domain == 'www.jjwxc.net':
      self.plugin = wwwjjwxc_BookCrawler(self.url)
    else:
      self.plugin = None
    #####################

    # 若找不到插件,設定valid = False,表示此網站不支援
    if self.plugin is None:
      self.valid = False
    else:
      self.valid = True

  def getinfo(self):
    self.plugin.getinfo()
    self.authorname = self.plugin.authorname
    self.title = self.plugin.title
    self.totalsection = self.plugin.totalsection

plugin資料夾

因各網站的HTML格式皆不相同,對應不同網域需要使用不同的plugin實作。

為了方便管理,便將各網站的plugin皆放置於此資料夾。

abstractclass.py

宣告抽象類別,定義plugin類別應有的屬性與方法。
未來開發的每支plugin程式都應繼承此抽象類別,由此來控管plugin屬性和方法的一致性。

class AbstractBookCrawler:
  def __init__(self, url):
    self.authorname = None
    self.title = None
    self.url = url
    self.totalsection = 0

  def getinfo():
    pass

wwwjjwxc_bookcrawler.py

此程式實作了www.jjwxc.net的方法。

  • init(self, url):主要繼承母類別的初始化。為了處理HTML亂碼問題,另外定義了encoding屬性使用。

  • getinfo():爬蟲程式的本體。

import requests
import re
from bs4 import BeautifulSoup
from crawler.plugin.abstractclass import AbstractBookCrawler

class wwwjjwxc_BookCrawler(AbstractBookCrawler):
  def __init__(self, url):
    super().__init__(url)
    self.encoding = 'gb18030'

  def getinfo(self):
    page = requests.get(self.url)
    page.encoding = self.encoding

    soup = BeautifulSoup(page.content, 'html.parser')
    title_tag = soup.find("span",itemprop="articleSection")
    author_tag = soup.find("span", itemprop="author")
    totalsection_tag = soup.find_all("tr", itemprop=["chapter","chapter newestChapter"])

    self.title = re.compile(r'>(.*)<').search(str(title_tag)).group(1)
    self.authorname = re.compile(r'>(.*)<').search(str(author_tag)).group(1)
    self.totalsection = totalsection_tag.__len__()

上一篇
Day15 - 建立模板
下一篇
Day17 - 安裝自己開發的套件
系列文
Python 30天自我挑戰30

尚未有邦友留言

立即登入留言