测试 z emoji i URL

发布: (2026年1月8日 GMT+8 06:06)
3 min read
原文: Dev.to

Source: Dev.to

前言

Twitter (X) 将推文限制为 280 个字符——超出会阻止发布。作为高级 DevOps 工程师,我曾花费数小时手动裁剪文本。于是我使用 Python + Tweepy v2 编写了自动化脚本,能够精确统计字符数(包括表情符号、URL、空格),并发布优化后的内容。Zero bullshit,pure engineering[1][6]。

精确字符计数:Unicode‑感知的字符串处理

Twitter 计数 字符,而非字节。Emoji 占 2‑4 个字符,URL 会被缩短为 23 个字符。标准的 len() 会失效。

import unicodedata
import re

def twitter_char_count(text: str) -> int:
    """Precyzyjne liczenie pod Twitter API v2. Obsługuje emoji, URL‑e, spacje."""
    # Normalizuj Unicode (NFC)
    text = unicodedata.normalize('NFC', text)

    # Skróć URL‑e do 23 znaków (Twitter standard)
    url_pattern = r'https?://[^\s<>"{}|\\^`\[\]]*'
    def shorten_url(match):
        return 'https://t.co/abc123'  # 23 chars
    text = re.sub(url_pattern, shorten_url, text)

    # Liczenie: każdy grapheme cluster = 1 char
    char_count = 0
    i = 0
    while i  str:
        """Skraca tekst pod limit, zachowując kluczowe słowa."""
        if twitter_char_count(long_text)  max_chars:
            sentences = clean_text.split('. ')
            if len(sentences) > 1:
                clean_text = '. '.join(sentences[:-1])
            else:
                # Fallback: truncate + [...]
                clean_text = clean_text[:max_chars-10] + '...'
                break

        return clean_text.strip() + ' ' + ' '.join(hashtags[-3:])

    def post_optimized(self, text: str) -> str:
        """Publikuje zoptymalizowany tweet."""
        optimized = self.optimize_tweet(text)
        print(f"Original: {twitter_char_count(text)} chars")
        print(f"Optimized: {twitter_char_count(optimized)} chars")

        response = self.client.create_tweet(text=optimized)
        return response.data['id']
# Użycie
optimizer = TwitterOptimizer()
tweet_id = optimizer.post_optimized(
    "Długi tekst o DevOps, Pythonie, Cloudflare Workers i LLM-ach który przekracza 280 znaków. "
    "Muszę go automatycznie skrócić używając precyzyjnego licznika znaków i Tweepy v2! "
    "https://github.com/tweepy #Python #DevOps #TwitterAPI"
)

速率限制

wait_on_rate_limit=True – 零手动限流[2]。

高级自动化:Threading + Cloudflare Workers

对于 >280字符 → 自动线程。额外:通过 Cloudflare Workers 代理实现 IP 轮换。

def create_thread(self, long_content: List[str]) -> List[str]:
    """Tworzy wątek z długiej treści."""
    thread_ids = []
    first_tweet = True

    for chunk in long_content:
        optimized = self.optimize_tweet(chunk)
        if first_tweet:
            response = self.client.create_tweet(text=optimized)
            thread_ids.append(response.data['id'])
            first_tweet = False
            reply_to = response.data['id']
        else:
            response = self.client.create_tweet(
                text=optimized,
                in_reply_to_tweet_id=reply_to
            )
            thread_ids.append(response.data['id'])
            reply_to = response.data['id']

    return thread_ids

# Bash deployment do Cloudflare Workers (proxy dla API calls)
"""
wrangler.toml:
name = "twitter-proxy"
main = "src/index.js"
compatibility_date = "2025-01-07"

# Deploy:
wrangler deploy
"""

经验

优化 + 线程化后参与度提升 17 %[6]。Cloudflare Workers 绕过速率限制(匿名 IP)。

结论

纯粹的工程胜利: 精确的字符计数 + Tweepy v2 = 零被拒的推文。通过线程和 Cloudflare 实现可扩展性。叛逆小贴士: 使用 wait_on_rate_limit=True —— Twitter 不喜欢激进的机器人。把代码放到 GitHub,部署到 Workers,忘掉它。

来源

  • [1] Tweepy + Twitter API v2 教程
  • [2] Twitter API v2 速率限制和分页
  • [6] 带分页的 tweepy.Client 示例
Back to Blog

相关文章

阅读更多 »