スクリプト置き場

Page last edited 1,533 日前
提供:新型コロナ総合Wiki
Jump to navigation Jump to search

魚拓作成用ブックマークレット[編集 | ソースを編集]

1 javascript:(function() { var url = location.href; var URLs =["http://web.archive.org/save/","https://archive.ph/?run=1&url=","http://megalodon.jp/?url="]; for( var i in URLs){ var redirect_url = URLs[i] + url ; window.open(redirect_url, "_blank"); };})()

時事通信のニュースのリンクをmedia wiki形式に書き換えるスクリプト(python3.8)[編集 | ソースを編集]

  1 #!/usr/bin/env python3
  2 # -*- coding: utf-8 -*-
  3 
  4 """
  5     このスクリプトはPython3.7以上で動くはずです。
  6     共同通信のニュースのURLからタイトルと日付を取出しMediaWiki形式でテキストに保存します
  7     テキストの保存例は次のようになっています
  8 
  9     ====year/month/day1====
 10     *[記事1のURL 記事のタイトル1]
 11     *[記事2のURL 記事のタイトル2]
 12 
 13     ====year/month/day2====
 14     *[記事3のURL 記事のタイトル3]
 15 
 16 
 17 
 18     文字コードがUTF-8で保存された1行に1URLあるテキストファイルから、URL先にアクセスしタイトルと日付を取出し指定した名前でutf-8で保存します.
 19 
 20     使い方:
 21     hoge
 22     ├── このpythonファイル.py
 23     └── urlリスト.txt
 24     のとき
 25 
 26     $ このpythonファイル.py ["urlリスト.txt"] ["出力するファイル名.txt"]
 27 
 28     と入力するとurlリスト.txtが以下のようにそのディレクトリに出力されます。
 29 
 30     hoge
 31     ├── このpythonファイル.py
 32     ├── 出力するファイル名.txt
 33     └── urlリスト.txt
 34 
 35 
 36 
 37 """
 38 import datetime
 39 import itertools
 40 import sys
 41 
 42 import pytz
 43 import requests
 44 from bs4 import BeautifulSoup
 45 
 46 
 47 def main(url_list_name: str = "urltext.txt", output_filename: str = "共同通信wiki用記事と日付.txt"):
 48     article_info_list = []
 49     url_list = import_url_lists(url_list_name)
 50 
 51     for url in url_list:
 52         content = get_url_content(url)  # httpでgetリクエストを送る
 53         article_info = scrap_article_information(content, url)  # bs4で記事から時刻とタイトルを取得
 54         article_info["url"] = url
 55         article_info_list.append(article_info)
 56 
 57     article_info_list.sort(key=lambda x: x["time"])  # 時刻順にソート
 58     wiki_data = change_to_media_wiki_format(article_info_list)  # 取得したデータをmedia wiki形式に変換
 59     save_to_text(wiki_data, output_filename)  # media wiki形式に変換したデータをテキストに保存
 60     # print(output_filename)
 61     # print(url_list)
 62     # print(article_info_list)
 63 
 64 
 65 def import_url_lists(path_text):
 66     """テキストファイルからURLを取得
 67     空白行は除去されるがテクストがURLかどうかは判断しない
 68     """
 69     with open(path_text, "r") as f:
 70         lines: list = f.read().splitlines()
 71         lines = [a for a in lines if a != '']  # 空白行除去
 72     return lines
 73 
 74 
 75 def get_url_content(url: str):
 76     """
 77     URLからHTMLを取得する
 78     HTTPステータスコードに問題があった場合処理を終了し標準出力にエラーコードなどを返す
 79     :param url:strのURLが入るようにしてください
 80     :return:
 81     """
 82     r = requests.get(url)
 83 
 84     if not r.status_code == 200:  # 接続が正常化か確認し、正常でなければプログラムを終了する
 85         print("インターネットの接続に問題があります。HTTPステータスコード{err_code}\n "
 86               "最後に読み込んでいたURLは\n {loaded_url}"
 87               .format(err_code=r.status_code, loaded_url=url))
 88         sys.exit(1)  # プロセスを終了
 89 
 90     return r.content
 91 
 92 
 93 def scrap_article_information(r: bytes,
 94                               url: str = "URLがscrap_article_information関数に渡されていません") -> dict:
 95     """
 96     記事から記事のタイトルと時間を取得します
 97     :type url:スクレピングしているurl。主にエラー発生時にどのURLでエラーが発生しているか調べるためのもの。省略可能
 98     :param r:requests.get(url)で取得したものが入るようにしてください
 99     :return:
100     """
101     soup = BeautifulSoup(r)
102 
103     if soup.find("title") is None:  # 記事の見出しの読み込み確認
104         print("記事のタイトルが読み込みできませんでした\n正しく記事を読みこめていますか?\n" +
105               "一度ブラウザで\n{url}\nを開き確認してみてください".format(url=url))
106         sys.exit(1)
107     article_tittle = soup.find("title").string
108 
109     if soup.find("time") is None:  # 時刻の読み込み確認
110         print("記事の時刻が読み込みできませんでした\n正しく記事を読みこめていますか?\n" +
111               "一度ブラウザで\n{url}\nを開き確認してみてください".format(url=url))
112         sys.exit(1)
113     time_string = soup.find("time", class_="main__date").contents[0]
114 
115     article_time = change_str_to_date_type(time_string)  # 文字列を時刻に型変換
116     article_dict = {"title": article_tittle, "time": article_time}
117     return article_dict
118 
119 
120 def change_str_to_date_type(article_time: str) -> datetime:
121     """
122         2017/4/8 03:05 (JST)といった月と日付が0埋めされていない文字列なので
123         Mac,Linuxでは%-m, %-dなどで動くがwindowsだとC言語の実装の影響で動かない
124         OS互換性のために仕方が無いので文字列を年,月,日付,時刻,タイムゾーンに分解して処理
125     """
126     article_date_time = [int(s) if len(s) == 1 else int(s) for s in article_time.split(" ")[0].split("/")] + \
127                         [int(s) for s in article_time.split(" ")[1].split(":")]  # 日付と時刻を読み込みやすい威容に整形
128     tz: datetime = None
129     if "JST" in article_time.split(" ")[1]:  # 文字列がJSTならばタイムジーンを東京に変更
130         tz = pytz.timezone('Asia/Tokyo')
131 
132     article_time = datetime.datetime(*article_date_time, tzinfo=tz)
133     return article_time
134 
135 
136 def change_to_media_wiki_format(data_wiki: list) -> str:
137     """
138     スクレピングしてきたデータをmedia wiki形式に変換する関数
139     :param data_wiki:
140     data_wikiの構造は予め時刻でソートされているリストを期待していて
141     [{"title":記事のタイトル, "time": 記事の時刻データ(タイムゾーンあり),"url":記事のurl},
142 
143     {"title":記事のタイトル, "time": 記事の時刻データ(タイムゾーンあり),"url":記事のurl}]
144     という風になっていることが前提
145 
146     :return:
147     """
148     out_text = ""  # type:str
149     for key, group in itertools.groupby(data_wiki, key=lambda m: m['time'].strftime("%Y/%m/%d/")):  # 日付でリストをグループ分け
150 
151         out_text += ("===={0}====\n".format(key))  # key(日付データをテキストに書き込み)
152 
153         for data_wiki in group:  # 記事のタイトルとURLをwiki形式に変換しテキストに書き込み
154             title = data_wiki["title"].split("\u3000")[0].split(" | ")[0]
155             try:  # 副見出しがある時だけ追加 ないときはIndexErrorが返ってくるので無視
156                 title += "  " + data_wiki["title"].split("\u3000")[1].split(" | ")[0]
157             except IndexError:
158                 pass
159 
160             url = data_wiki["url"]
161             link = "*[{url} {title}]\n".format(url=url, title=title)
162             out_text += link
163     return out_text
164 
165 
166 def save_to_text(wiki_data: str, name: str):
167     with open(name, "w", encoding="utf-8") as f:
168         f.write(wiki_data)
169     print("{name}として保存しました".format(name=name))
170 
171 
172 if __name__ == "__main__":
173     url_list_file_path = sys.argv[1]
174     out_text_name: str = sys.argv[2]
175     main(url_list_file_path, out_text_name)