helper.urlDeployment のソースコード

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
引数URLのサイトにアクセスして、タイトルと最終画像URLをスクレイピングする。
最終画像URLの数字を展開した、URLリストをファイルに保存して、irvineに渡す。
    http:/hoge/10.jpg

    http:/hoge/1.jpg ~ http:/hoge/10.jpg
irvineが起動してダウンロードが開始されるので、ダウンロードが終わったらirvineを手動で終了する。
irvineが終了したらダウンロードファイルをチェックする。
失敗している時は、拡張子を変えて、ファイルに保存して、irvineに渡す。
成功している時は、リネームしてzipして削除する。

Todo:
    - docstringを整える
"""
import sys
import copy
import inspect
import datetime
from dataclasses import dataclass
from urllib.parse import urlparse  # URLパーサー
from urllib.parse import urlunparse
import helper.chromeDriver
import helper.webFile
import helper.webFileList

# local source
from const import *


[ドキュメント] @dataclass(frozen=True) class UrlDeploymentValue: """URL展開クラスの値オブジェクト """ url: str selectors: list title: str image_urls: list def __init__(self, url, selectors, title, image_urls): """完全コンストラクタパターン :param url: str 処理対象サイトURL :param selectors: list スクレイピングする際のセレクタリスト :param title: str 取得したサイトタイトル :param image_urls: list 取得した画像のURLリスト """ if url is not None: if not self.is_url_only(url): raise ValueError(f"{self.__class__.__name__}.{inspect.stack()[1].function}" f"不正:引数urlがURLではない[{url}]") object.__setattr__(self, "url", url) if selectors is not None: object.__setattr__(self, "selectors", selectors) if title is not None: object.__setattr__(self, "title", title) if image_urls is not None: for image_url in image_urls: if not self.is_url_only(image_url): raise ValueError(f"{self.__class__.__name__}.{inspect.stack()[1].function}" f"不正:引数last_image_urlがurlではない[{image_url}]") object.__setattr__(self, "image_urls", image_urls)
[ドキュメント] @staticmethod def is_url_only(string: str) -> bool: return len(urlparse(string).scheme) > 0
[ドキュメント] class UrlDeployment: """ 「UrlDeploymentValue 値オブジェクト」 「str スクレイプ対象URL, list selectors」が引数で渡されるケース 「str 末尾画像URL, str タイトル」が引数で渡されるケース """ value_object: UrlDeploymentValue = None url_list: list = [] def __init__(self, value_object, selectors_or_title=None): if value_object is not None: if isinstance(value_object, UrlDeploymentValue): self.value_object = value_object elif isinstance(value_object, str): # URLかチェックする __parse = urlparse(value_object) if not __parse.scheme: print('引数が不正です。URLではない?') sys.exit(1) if __parse.path[-4:] == '.jpg' or __parse.path[-4:] == '.png': __image_url = value_object __title = selectors_or_title __selectors = None else: __selectors = selectors_or_title page_url = value_object __driver = helper.chromeDriver.ChromeDriver(value_object, __selectors) items = __driver.get_items() _title = None if 'title_jp' in items: _title = items['title_jp'] title_sub = None if 'title_en' in items: title_sub = items['title_en'] image_urls = None if 'image_urls' in items: image_urls = items['image_urls'] last_image_url = None if 'image_url' in items: last_image_url = items['image_url'] print(_title, title_sub, last_image_url, image_urls) if _title and isinstance(_title, list): _title = _title[0] if title_sub and isinstance(title_sub, list): title_sub = title_sub[0] if last_image_url and isinstance(last_image_url, list): last_image_url = last_image_url[0] if image_urls and image_urls[0]: last_image_url = image_urls[0] if not last_image_url: raise ValueError(f"エラー:last_image_urlが不正[{last_image_url}]") if not _title: if not title_sub: # タイトルが得られない時は、タイトルを日時文字列にする now = datetime.datetime.now() _title = f'{now:%Y%m%d_%H%M%S}' else: _title = title_sub __title = __driver.fixed_file_name(_title) url_title = __driver.fixed_file_name(page_url) target_path = f'{__title}{url_title}.html' __driver.save_source(target_path) __image_url = last_image_url __image_urls = self.__deployment(__image_url) self.value_object = UrlDeploymentValue(value_object, __selectors, __title, __image_urls, ) def __deployment(self, image_url): """末尾画像URLを展開して、URLリスト=url_listを作る :param image_url: str 末尾画像URL :return: list 展開した画像URLリスト """ if not image_url: print('引数が不正です。空です。') sys.exit(1) __parse = urlparse(image_url) if not __parse.scheme: print('引数が不正です。URLではない?') sys.exit(1) # pathを/前後で分ける __path_before_name = __parse.path[:__parse.path.rfind('/') + 1] __path_after_name = __parse.path[__parse.path.rfind('/') + 1:] print(__path_before_name) print(__path_after_name) # path_after_nameを.前後で分ける __base_name = __path_after_name[:__path_after_name.rfind('.')] __extend_name = __path_after_name[__path_after_name.rfind('.'):] print(__base_name) print(__extend_name) if not __base_name.isdecimal(): print('引数が不正です。数値ではない?') sys.exit(1) __count = int(__base_name) for d_count in range(__count): self.url_list.append(urlunparse((__parse.scheme, __parse.netloc, __path_before_name + str(d_count + 1) + __extend_name, __parse.params, __parse.query, __parse.fragment))) return self.url_list
[ドキュメント] def get_title(self): """タイトル取得 :return: str タイトル """ return copy.deepcopy(self.value_object.title)
[ドキュメント] def get_image_urls(self): """画像リスト取得 :return: list 画像リスト """ return copy.deepcopy(self.value_object.image_urls)