「利用者:夜泣き/スクリプト」の版間の差分

→‎コード: 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.10 2023/12/17恒心
ver4.1.11 2023/12/18恒心


当コードは恒心停止してしまった https://rentry.co/7298g の降臨ショーツイート自動収集スクリプトの復刻改善版です
当コードは恒心停止してしまった https://rentry.co/7298g の降臨ショーツイート自動収集スクリプトの復刻改善版です
155行目: 155行目:
         """
         """


         incremented_num_default: Final[int] = 4
         incremented_num_default: Final[int] = 0
         """Final[int]: ツイートURLの数字部分うち、インクリメントする桁のデフォルト値。
         """Final[int]: ツイートURLの数字部分うち、インクリメントする桁のデフォルト値。


1,110行目: 1,110行目:


         # 日付取得
         # 日付取得
         timeline_item: Final[Tag | NavigableString | None] = BeautifulSoup(
         tweet_link: Final[Tag | NavigableString | None] = BeautifulSoup(
             self._nitter_page, 'html.parser'
             self._nitter_page, 'html.parser'
         ).find(class_='timeline-item')
         ).find(class_='tweet-link')
         assert isinstance(timeline_item, Tag)
         assert isinstance(tweet_link, Tag)
         date: Final[datetime] = self._tweet_date(timeline_item)
        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, tweet: Tag) -> datetime:
     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:
             tweet (Tag): ツイート内容である ``.timeline-item`` タグを表すbeautifulsoup4タグ。
             url (str): ツイートのURL。


         Returns:
         Returns:
             datetime: ツイートの時刻。
             datetime: ツイートの時刻。
         """
         """
         tweet_date: Final[Tag | NavigableString | None] = tweet.find(
         id: int = int(url.split('/')[-1])
            class_='tweet-date')
         timestamp: float = ((id >> 22) + 1_288_834_974_657) / 1000.
        assert isinstance(tweet_date, Tag)
         return datetime.fromtimestamp(timestamp, tz=ZoneInfo('Asia/Tokyo'))
        tweet_date_a: Final[Tag | None] = tweet_date.a
         assert tweet_date_a is not None
        date_str: Final[str | list[str] | None] = tweet_date_a.get('title')
        assert isinstance(date_str, str)
         return datetime.strptime(
            date_str,
            '%b %d, %Y · %I:%M %p %Z').replace(
            tzinfo=ZoneInfo('UTC')).astimezone(
            ZoneInfo('Asia/Tokyo'))


     def _fetch_tweet_media(
     def _fetch_tweet_media(
1,748行目: 1,745行目:
                 if not_match:
                 if not_match:
                     continue
                     continue
            # 日付の更新処理
            date: Final[datetime] = self._tweet_date(tweet)
            self._table_builder.next_day_if_necessary(date)


             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)
    @override
    def _tweet_date(self, tweet: Tag) -> datetime:
        # TODO: 日付が合わないのを修正する
        datetime_tag: Final[Tag | None] = tweet.select('time[datetime]')[-1]
        assert datetime_tag is not None
        datetime_str: Final[str | list[str] | None] = (
            datetime_tag.get('datetime'))
        assert isinstance(datetime_str, str)
        raw_time: Final[datetime] = datetime.strptime(
            datetime_str, '%Y-%m-%dT%H:%M:%S.000Z')
        return raw_time.replace(tzinfo=ZoneInfo('Asia/Tokyo'))


     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(article)
                 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)


匿名利用者