jxxghp / MoviePilot-Plugins

MoviePilot官方插件市场
GNU General Public License v3.0
151 stars 219 forks source link

[错误汇报] 站点数据统计插件馒头访问403 #425

Closed Devinaille closed 1 month ago

Devinaille commented 1 month ago

--- 20240801更新 ---

站点管理中将域名修改为https://kp.xxx.cc/(已脱敏,xxx为正确域名),报错信息变为

【DEBUG】2024-08-01 09:47:24,549 - http.py - 请求失败: HTTPSConnectionPool(host='api.xxx.cc', port=443): Max retries exceeded with url: /api/member/profile (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)')))

在mp容器中使用moviepiolt用户中的python3执行以下代码

import requests
requests.request(method='get', url='https://api.xxx.cc/api/member/profile')

可得到相同结果

>>> import requests
>>> requests.request(method='get', url='https://api.xxx.cc/api/member/profile')

Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 468, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 1097, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.11/site-packages/urllib3/connection.py", line 642, in connect
    sock_and_verified = _ssl_wrap_socket_and_match_hostname(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/connection.py", line 783, in _ssl_wrap_socket_and_match_hostname
    ssl_sock = ssl_wrap_socket(
               ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/util/ssl_.py", line 471, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/util/ssl_.py", line 515, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/ssl.py", line 517, in wrap_socket
    return self.sslsocket_class._create(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/ssl.py", line 1075, in _create
    self.do_handshake()
  File "/usr/local/lib/python3.11/ssl.py", line 1346, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLEOFError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 791, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 492, in _make_request
    raise new_e
urllib3.exceptions.SSLError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)

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

Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/requests/adapters.py", line 486, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 845, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/urllib3/util/retry.py", line 515, in increment
    raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='api.xxx.cc', port=443): Max retries exceeded with url: /api/member/profile (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.11/site-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/requests/adapters.py", line 517, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='api.xxx.cc', port=443): Max retries exceeded with url: /api/member/profile (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)')))

带上x-api-token的header(均脱敏)

r = requests.request(method='get', url='https://api.xxx.cc/api/member/profile', headers={'x-api-key': 'xxxxxxx'})

能正常访问,但是返回以下信息

{"message":"Request method 'GET' is not supported","data":null,"code":"1"}

查看馒头接口代码可知该接口为post方法,改为以下代码即可正常获得返回信息

r = requests.request(method='post', url='https://api.xxx.cc/api/member/profile', headers={'x-api-key': 'xxxxxxx'})

但反过来查看MP的插件代码

...
                # 普通模式
                res = RequestUtils(cookies=site_cookie,
                                   session=session,
                                   ua=ua,
                                   proxies=proxies
                                   ).get_res(url=url)
...

build方法中使用的是get_res方法,并且没有携带x-api-header,所以不能请求成功,请大佬看看这部分怎么修改合适

--- 以下为原始信息---

插件统计馒头信息时出现以下错误(信息已脱敏),在站点管理功能中是测试正常且能获取到种子列表

【DEBUG】2024-07-25 09:05:06,899 - sitestatistic - 站点 馒头 url=https://api.xxx.cc/,site_cookie=,ua=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.57,api_key=xxxxx,token=xxxxx,proxy=0
【ERROR】2024-07-25 09:05:47,976 - sitestatistic - 站点 馒头 连接失败,状态码:403

经排查,怀疑如下: 插件build函数中访问网页的代码

 def build(self, site_info: CommentedMap) -> Optional[ISiteUserInfo]:
        """
        构建站点信息
        """
        site_name = site_info.get("name")
        site_cookie = site_info.get("cookie")
        apikey = site_info.get("apikey")
        token = site_info.get("token")
        if not site_cookie and not apikey and not token:
            return None
        url = site_info.get("url")
        proxy = site_info.get("proxy")
        ua = site_info.get("ua")
        # 会话管理
        with requests.Session() as session:
            proxies = settings.PROXY if proxy else None
            proxy_server = settings.PROXY_SERVER if proxy else None
            render = site_info.get("render")
            logger.debug(f"站点 {site_name} url={url},site_cookie={site_cookie},ua={ua},api_key={apikey},token={token},proxy={proxy}")
            if render:
                # 演染模式
                html_text = PlaywrightHelper().get_page_source(url=url,
                                                               cookies=site_cookie,
                                                               ua=ua,
                                                               proxies=proxy_server)
            else:
                # 普通模式
                res = RequestUtils(cookies=site_cookie,
                                   session=session,
                                   ua=ua,
                                   proxies=proxies
                                   ).get_res(url=url)
                if res and res.status_code == 200:
    .......

可以看到请求中并没有带上header,也就是说访问馒头时不会带上x-api-key及Authorization,所以必然403

Andy-Home commented 2 weeks ago

请教这个问题解决了么?