→コード: v4.1.11 魚拓を探すときに日付が合わない問題を修正
>Fet-Fe (→コード: v4.1.10 魚拓からツイートを探すモードで、x.comからのリダイレクトが取れていなかったのを修正。_get_tweet_from_archiveが失敗しても未掲載のurl一覧だけは最悪取れるように修正) |
>Fet-Fe (→コード: v4.1.11 魚拓を探すときに日付が合わない問題を修正) |
||
11行目: | 11行目: | ||
"""Twitter自動収集スクリプト | """Twitter自動収集スクリプト | ||
ver4.1. | ver4.1.11 2023/12/18恒心 | ||
当コードは恒心停止してしまった https://rentry.co/7298g の降臨ショーツイート自動収集スクリプトの復刻改善版です | 当コードは恒心停止してしまった https://rentry.co/7298g の降臨ショーツイート自動収集スクリプトの復刻改善版です | ||
155行目: | 155行目: | ||
""" | """ | ||
incremented_num_default: Final[int] = | incremented_num_default: Final[int] = 0 | ||
"""Final[int]: ツイートURLの数字部分うち、インクリメントする桁のデフォルト値。 | """Final[int]: ツイートURLの数字部分うち、インクリメントする桁のデフォルト値。 | ||
1,110行目: | 1,110行目: | ||
# 日付取得 | # 日付取得 | ||
tweet_link: Final[Tag | NavigableString | None] = BeautifulSoup( | |||
self._nitter_page, 'html.parser' | self._nitter_page, 'html.parser' | ||
).find(class_=' | ).find(class_='tweet-link') | ||
assert isinstance( | assert isinstance(tweet_link, Tag) | ||
date: Final[datetime] = self._tweet_date( | href: Final[str | list[str] | None] = tweet_link.get('href') | ||
assert isinstance(href, str) | |||
date: Final[datetime] = self._tweet_date( | |||
href.split('#')[0]) # フラグメント識別子を除去 | |||
self._table_builder: TableBuilder = TableBuilder(date) | self._table_builder: TableBuilder = TableBuilder(date) | ||
1,364行目: | 1,367行目: | ||
return FfmpegStatus.FAILED | return FfmpegStatus.FAILED | ||
def _tweet_date(self, | def _tweet_date(self, url: str) -> datetime: | ||
"""ツイートの時刻を取得する。 | """ツイートの時刻を取得する。 | ||
URLのIDから、Snowflakeの手順を逆算してタイムスタンプを計算している。 | |||
https://github.com/twitter-archive/snowflake/blob/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231/src/main/scala/com/twitter/service/snowflake/IdWorker.scala#L91 | |||
Args: | Args: | ||
url (str): ツイートのURL。 | |||
Returns: | Returns: | ||
datetime: ツイートの時刻。 | datetime: ツイートの時刻。 | ||
""" | """ | ||
id: int = int(url.split('/')[-1]) | |||
timestamp: float = ((id >> 22) + 1_288_834_974_657) / 1000. | |||
return datetime.fromtimestamp(timestamp, tz=ZoneInfo('Asia/Tokyo')) | |||
return datetime. | |||
def _fetch_tweet_media( | def _fetch_tweet_media( | ||
1,748行目: | 1,745行目: | ||
if not_match: | if not_match: | ||
continue | continue | ||
tweet_link: Final[Tag | NavigableString | None] = tweet.find( | tweet_link: Final[Tag | NavigableString | None] = tweet.find( | ||
1,761行目: | 1,754行目: | ||
self.TWITTER_URL, | self.TWITTER_URL, | ||
self._url_fragment_pattern.sub('', href)) | self._url_fragment_pattern.sub('', href)) | ||
# 日付の更新処理 | |||
date: Final[datetime] = self._tweet_date(tweet_url) | |||
self._table_builder.next_day_if_necessary(date) | |||
tweet_callinshow_template: Final[str] = self._callinshowlink_url( | tweet_callinshow_template: Final[str] = self._callinshowlink_url( | ||
2,151行目: | 2,148行目: | ||
else: | else: | ||
self._next_url(accessor, tweet_url_prefix, incremented_num + 1) | self._next_url(accessor, tweet_url_prefix, incremented_num + 1) | ||
def _parse_images(self, soup: Tag, | def _parse_images(self, soup: Tag, | ||
2,297行目: | 2,282行目: | ||
logger.debug(url_pair.url + 'を整形しますを') | logger.debug(url_pair.url + 'を整形しますを') | ||
tweet_date: Final[datetime] = self._tweet_date( | tweet_date: Final[datetime] = self._tweet_date(url_pair.url) | ||
table_builder.next_day_if_necessary(tweet_date) | table_builder.next_day_if_necessary(tweet_date) | ||