Twitter API 媒体上传失败,出现 FileNotFoundError

0 投票
1 回答
40 浏览
提问于 2025-04-14 16:39

我想做的事情

我正在编写一个Twitter机器人,它可以用Python库“Twikit”创建带有一些媒体的推文。下面是我写的Python代码“betsuaka_test.py”:

from twikit import Client

client = Client('ja')

client.login(
        auth_info_1='xxxxxxxxx',
        auth_info_2='foobar@gmail.com',
        password='xxxxxxxx'
)

TWEET_TEXT = 'テスト投稿2'
MEDIA_IDS = [
        client.upload_media('https://i.imgur.com/ZFMaW5h.png',0)
]
client.create_tweet(TWEET_TEXT, MEDIA_IDS)

发生了什么

当我用 python3 betsuaka_test.py 运行这段代码时,我的命令行交替返回了两种错误信息

[错误信息 1]

ubuntunaoki@LAPTOP-7Q7QL2PR:~$ python3 betsuaka_test.py
Traceback (most recent call last):
  File "/home/ubuntunaoki/betsuaka_test.py", line 13, in <module>
    client.upload_media('https://i.imgur.com/ZFMaW5h.png',0)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 568, in upload_media
    img_size = os.path.getsize(source)
  File "/usr/lib/python3.10/genericpath.py", line 50, in getsize
    return os.stat(filename).st_size
FileNotFoundError: [Errno 2] No such file or directory: 'https://i.imgur.com/ZFMaW5h.png'

[错误信息 2]

ubuntunaoki@LAPTOP-7Q7QL2PR:~$ python3 betsuaka_test.py
Traceback (most recent call last):
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 69, in map_httpcore_exceptions
    yield
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 233, in handle_request
    resp = self._pool.handle_request(req)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection_pool.py", line 216, in handle_request
    raise exc from None
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection_pool.py", line 196, in handle_request
    response = connection.handle_request(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection.py", line 101, in handle_request
    return self._connection.handle_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 143, in handle_request
    raise exc
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 93, in handle_request
    self._send_request_headers(**kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 151, in _send_request_headers
    with map_exceptions({h11.LocalProtocolError: LocalProtocolError}):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions
    raise to_exc(exc) from exc
httpcore.LocalProtocolError: Illegal header value b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 '

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/ubuntunaoki/betsuaka_test.py", line 5, in <module>
    client.login(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 138, in login
    guest_token = self._get_guest_token()
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 62, in _get_guest_token
    response = self.http.post(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/http.py", line 54, in post
    return self.request('POST', url, **kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/http.py", line 25, in request
    response = self.client.request(method, url, **kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 827, in request
    return self.send(request, auth=auth, follow_redirects=follow_redirects)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 914, in send
    response = self._send_handling_auth(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 942, in _send_handling_auth
    response = self._send_handling_redirects(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 979, in _send_handling_redirects
    response = self._send_single_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 1015, in _send_single_request
    response = transport.handle_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 232, in handle_request
    with map_httpcore_exceptions():
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 86, in map_httpcore_exceptions
    raise mapped_exc(message) from exc
httpx.LocalProtocolError: Illegal header value b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 '

为什么会这样呢?

  • “Twikit”不仅可以使用本地的图片文件,还可以使用网络上的图片。
  • 这个图片链接 https://i.imgur.com/ZFMaW5h.png 是有效的,当我在浏览器的地址栏输入这个链接时,想要的图片会显示出来。

新的尝试

我尝试了一些修改。

  • 从图片链接获取图片文件,并把它放到一个变量 image_file 中。
  • 然后,直接把这个二进制文件放入 update_media() 函数中。
from twikit import Client

client = Client('ja')

client.login(
        auth_info_1='xxxxxxx',
        auth_info_2='xxxxxx@gmail.com',
        password='xxxxxx'
)
import base64


image_file_path = 'https://i.imgur.com/ZFMaW5h.png'

with open(image_file_path, mode='rb') as f:
    image_file = f.read()

# base64エンコードする
binary_file_b64 = base64.b64encode(image_file)

# base64エンコードしたバイナリデータをターミナルに表示してみる
print(binary_file_b64)

TWEET_TEXT = 'テスト投稿2'
https://avatars.githubusercontent.com/u/7451118?s=200&v=4MEDIA_IDS = [        client.upload_media(binary_file_b64,0)
]
client.create_tweet(TWEET_TEXT, MEDIA_IDS)

但是又出现了另外两条错误信息:

Traceback (most recent call last):
  File "/home/ubuntunaoki/betsuaka_test.py", line 15, in <module>
    with open(image_file_path, mode='rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'https://i.imgur.com/ZFMaW5h.png'
Traceback (most recent call last):
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 69, in map_httpcore_exceptions
    yield
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 233, in handle_request
    resp = self._pool.handle_request(req)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection_pool.py", line 216, in handle_request
    raise exc from None
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection_pool.py", line 196, in handle_request
    response = connection.handle_request(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection.py", line 101, in handle_request
    return self._connection.handle_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 143, in handle_request
    raise exc
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 93, in handle_request
    self._send_request_headers(**kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 151, in _send_request_headers
    with map_exceptions({h11.LocalProtocolError: LocalProtocolError}):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions
    raise to_exc(exc) from exc
httpcore.LocalProtocolError: Illegal header value b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 '

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/ubuntunaoki/betsuaka_test.py", line 5, in <module>
    client.login(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 138, in login
    guest_token = self._get_guest_token()
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 62, in _get_guest_token
    response = self.http.post(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/http.py", line 54, in post
    return self.request('POST', url, **kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/http.py", line 25, in request
    response = self.client.request(method, url, **kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 827, in request
    return self.send(request, auth=auth, follow_redirects=follow_redirects)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 914, in send
    response = self._send_handling_auth(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 942, in _send_handling_auth
    response = self._send_handling_redirects(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 979, in _send_handling_redirects
    response = self._send_single_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 1015, in _send_single_request
    response = transport.handle_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 232, in handle_request
    with map_httpcore_exceptions():
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 86, in map_httpcore_exceptions
    raise mapped_exc(message) from exc
httpx.LocalProtocolError: Illegal header value b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 '

1 个回答

0

根据来自 twikit 的 文档,我们可以了解 upload_media() 这个方法的使用方式:

Uploads media to twitter.

Parameters:
media_path (str | bytes) – The file path or binary data of the media to be uploaded.

index (int) – The index of the media segment being uploaded. Should start from 0 and increment by 1 for each subsequent upload.

Returns:
The media ID of the uploaded media.

Return type:
int

你需要把 media_path 这个参数设置为你本地文件的路径,或者这个文件的字节数据。

我建议你先从源头获取图片,把结果转换成字节数据,然后再把这些二进制数据传递给 upload_media() 这个方法。

我觉得我的回答能稍微帮助你实现你的目标。

撰写回答