Skip to content

hanime1.me and rule34video.com support#14

Open
kosdzzew5 wants to merge 7 commits into
cynthia2006:masterfrom
kosdzzew5:master
Open

hanime1.me and rule34video.com support#14
kosdzzew5 wants to merge 7 commits into
cynthia2006:masterfrom
kosdzzew5:master

Conversation

@kosdzzew5

Copy link
Copy Markdown

rule34video.com videos are already supported by upstream, but adding playlist and tag and search and the like.

the tests/ folder contains some end to end tests, i find them useful but may be discarded, i see you are currently not using this type of tests.

@cynthia2006

Copy link
Copy Markdown
Owner

Great PR! But, I've never heard about hanime1.me before. Is it a niche website?

@kosdzzew5

Copy link
Copy Markdown
Author

Thanks for taking a look at it!
It is not particularly niche, but the site is mostly Chinese, so its less well known in English speaking communities.

Comment thread yt_dlp_plugins/extractor/hanime1.py Outdated
Comment thread yt_dlp_plugins/extractor/hanime1.py Outdated
Comment thread yt_dlp_plugins/extractor/hanime1.py Outdated
Comment thread yt_dlp_plugins/extractor/hanime1.py Outdated
Comment thread yt_dlp_plugins/extractor/hanime1.py Outdated
Comment thread yt_dlp_plugins/extractor/hanime1.py Outdated
Comment thread yt_dlp_plugins/extractor/hanime1.py Outdated
@cynthia2006

Copy link
Copy Markdown
Owner

The reason I'm not including tests is because these websites—shady as they are—have no guarantees on their behavior. The hanime.tv extractor used to include a test, but it has been removed.

@cynthia2006

Copy link
Copy Markdown
Owner

rule34video.com videos are already supported by upstream, but adding playlist and tag and search and the like.

Maybe you're better off making a PR in the upstream than here. The maintainers can be slow, but it would reach to a wider audience.

@kosdzzew5 kosdzzew5 requested a review from cynthia2006 June 4, 2026 19:04
@kosdzzew5

kosdzzew5 commented Jun 4, 2026

Copy link
Copy Markdown
Author

thanks for the feedback!
I think i fixed everything you mentioned, also moved the other helpers to member functions
the

Using a set() or frozenset() is a better option here.

is valid, but actually used an orderedset instead, to preserve playlist video order.

Regarding upstream: thanks for the recommendation, yeah, i'll try to get it merged there later on

@cynthia2006

Copy link
Copy Markdown
Owner

Does the playlist order have to be preserved?

@cynthia2006

cynthia2006 commented Jun 5, 2026

Copy link
Copy Markdown
Owner

@kosdzzew5 I tried your fork on my machine, but it fails with a HTTP 403.

$ yt-dlp -F 'https://hanime1.me/watch?v=22673'
[Hanime1] Extracting URL: https://hanime1.me/watch?v=22673
[Hanime1] 22673: Downloading webpage
ERROR: [Hanime1] 22673: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/watch?v=99690'
[Hanime1] Extracting URL: https://hanime1.me/watch?v=99690
[Hanime1] 99690: Downloading webpage
ERROR: [Hanime1] 99690: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/watch?v=155209&list=435600&sort=latest'
[Hanime1] Extracting URL: https://hanime1.me/watch?v=155209&list=435600&sort=latest
[Hanime1] 155209: Downloading webpage
ERROR: [Hanime1] 155209: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/user/689220/uploaded'
[hanime1:user] Extracting URL: https://hanime1.me/user/689220/uploaded
[hanime1:user] 689220: Downloading webpage
ERROR: [hanime1:user] 689220: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/user/689220'
[hanime1:user] Extracting URL: https://hanime1.me/user/689220
[hanime1:user] 689220: Downloading webpage
ERROR: [hanime1:user] 689220: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/user/979597/likes'
[hanime1:user:likes] Extracting URL: https://hanime1.me/user/979597/likes
[hanime1:user:likes] 979597: Downloading webpage
ERROR: [hanime1:user:likes] 979597: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/user/1262549/saves'
[hanime1:user:saves] Extracting URL: https://hanime1.me/user/1262549/saves
[hanime1:user:saves] 1262549: Downloading webpage
ERROR: [hanime1:user:saves] 1262549: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/user/666925/histories'
[hanime1:user:history] Extracting URL: https://hanime1.me/user/666925/histories
[hanime1:user:history] 666925: Downloading webpage
ERROR: [hanime1:user:history] 666925: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/user/854091/playlists'
[hanime1:user:playlists] Extracting URL: https://hanime1.me/user/854091/playlists
[hanime1:user:playlists] 854091: Downloading webpage
ERROR: [hanime1:user:playlists] 854091: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
$ yt-dlp -F 'https://hanime1.me/subscriptions'
[hanime1:subscriptions] Extracting URL: https://hanime1.me/subscriptions
[download] Downloading playlist: Subscriptions
[hanime1:subscriptions] subscriptions: Downloading page 1
ERROR: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
[hanime1:subscriptions] Playlist Subscriptions: Downloading 1 items
[download] Finished downloading playlist: Subscriptions
$ yt-dlp -F 'https://hanime1.me/subscriptions?genre=Cosplay'
[hanime1:subscriptions] Extracting URL: https://hanime1.me/subscriptions?genre=Cosplay
[download] Downloading playlist: Subscriptions
[hanime1:subscriptions] subscriptions: Downloading page 1
ERROR: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
[hanime1:subscriptions] Playlist Subscriptions: Downloading 1 items
[download] Finished downloading playlist: Subscriptions
$ yt-dlp -F 'https://hanime1.me/search?query=%E3%83%A1%E3%83%AA%E3%83%BC%E3%83%BB%E3%82%B8%E3%82%A7%E3%83%BC%E3%83%B3&genre=%E8%A3%8F%E7%95%AA'
[hanime1:search] Extracting URL: https://hanime1.me/search?query=%E3%83%A1%E3%83%AA%E3%83%BC%E3%83%BB%E3%82%B8%E3%82%A7%E3%83%BC%E...e=%E8%A3%8F%E7%95%AA
[download] Downloading playlist: メリー・ジェーン - 裏番
[hanime1:search] query=メリー・ジェーン&genre=裏番: Downloading page 1
ERROR: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
[hanime1:search] Playlist メリー・ジェーン - 裏番: Downloading 1 items
[download] Finished downloading playlist: メリー・ジェーン - 裏番
$ yt-dlp -F 'https://hanime1.me/search?query=Somato'
[hanime1:search] Extracting URL: https://hanime1.me/search?query=Somato
[download] Downloading playlist: Somato
[hanime1:search] query=Somato: Downloading page 1
ERROR: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
[hanime1:search] Playlist Somato: Downloading 1 items
[download] Finished downloading playlist: Somato
$ yt-dlp -F 'https://hanime1.me/search?tags%5B%5D=%E6%8E%A5%E5%90%BB&genre=%E8%A3%8F%E7%95%AA'
[hanime1:search] Extracting URL: https://hanime1.me/search?tags%5B%5D=%E6%8E%A5%E5%90%BB&genre=%E8%A3%8F%E7%95%AA
[download] Downloading playlist: 接吻 - 裏番
[hanime1:search] tags[]=接吻&genre=裏番: Downloading page 1
ERROR: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
[hanime1:search] Playlist 接吻 - 裏番: Downloading 1 items
[download] Finished downloading playlist: 接吻 - 裏番
$ yt-dlp -F 'https://hanime1.me/search?genre=%E8%A3%8F%E7%95%AA'
[hanime1:search] Extracting URL: https://hanime1.me/search?genre=%E8%A3%8F%E7%95%AA
[download] Downloading playlist: 裏番
[hanime1:search] genre=裏番: Downloading page 1
ERROR: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
[hanime1:search] Playlist 裏番: Downloading 1 items
[download] Finished downloading playlist: 裏番

@kosdzzew5

Copy link
Copy Markdown
Author

Thanks for testing and for the detailed log! I tried to reproduce this and couldn't, so I think the problem is on the network/client side rather than in the extractor.

Repro steps

I installed the PR branch as a plugin into two clean, separate virtualenvs (nothing from my dev tree leaking in), then ran the same public URL https://hanime1.me/watch?v=22673:

curl_cffi no curl_cffi
neither flag works works
--impersonate chrome works -
--cookies-from-browser works works
both works -

A 403 on every endpoint might be an IP / region block from Cloudflare. Maybe the site is IP blocked or Cloudflare is serving a challenge your client can't pass?

Have you tried perhaps with curl_cffi 0.15? yt-dlp currently only accepts curl_cffi 0.10.x-0.14.x, 0.15 silently fails.

Can you give more info?

  1. Whether the same URL opens in a normal browser on that machine, and whether a plain curl -I 'https://hanime1.me/watch?v=22673' also returns 403.
  2. If 1. worked: the full yt-dlp -v banner for one failing run, especially the Optional libraries line

If a plain browser/curl from the same box also gets 403, it's a Cloudflare block

@cynthia2006

Copy link
Copy Markdown
Owner

It's not IP blocked, because I could just solve the captcha and access the site.

$ curl -I 'https://hanime1.me/watch?v=22673'
HTTP/2 403 
date: Sun, 07 Jun 2026 03:05:58 GMT
content-type: text/html; charset=UTF-8
content-length: 5267
...

@cynthia2006

Copy link
Copy Markdown
Owner

These are the logs.

$ yt-dlp -vF 'https://hanime1.me/watch?v=22673'
[debug] Command-line config: ['-vF', 'https://hanime1.me/watch?v=22673']
[debug] User config "/home/cynthia/.config/yt-dlp/config": ['-N', '10']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version stable@2026.03.17 from yt-dlp/yt-dlp [04d6974f5] (pip)
[debug] Python 3.14.5 (CPython x86_64 64bit) - Linux-7.0.10-arch1-1-x86_64-with-glibc2.43 (OpenSSL 3.6.2 7 Apr 2026, glibc 2.43)
[debug] exe versions: ffmpeg 8.1.1 (setts), ffprobe 8.1.1, rtmpdump 2.6
[debug] Optional libraries: certifi-2026.05.20, curl_cffi-0.14.0, sqlite3-3.53.1
[debug] JS runtimes: deno-2.6.10
[debug] Proxy map: {}
[debug] Request Handlers: urllib, curl_cffi
[debug] Extractor Plugins: Hanime1IE, Hanime1PlaylistIE, Hanime1SearchIE, Hanime1SubscriptionsIE, Hanime1UserHistoryIE, Hanime1UserIE, Hanime1UserLikesIE, Hanime1UserPlaylistsIE, Hanime1UserSavesIE, HanimeRedIE, HanimeTVIE, HentaiHavenIE, HentaimamaIE, HstreamIE, OhentaiIE, OppaiStreamIE
[debug] Plugin directories: /home/cynthia/Public/hanime-plugin/yt_dlp_plugins
[debug] Loaded 1880 extractors
[Hanime1] Extracting URL: https://hanime1.me/watch?v=22673
[Hanime1] 22673: Downloading webpage
ERROR: [Hanime1] 22673: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: Forbidden>)
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/extractor/common.py", line 765, in extract
    ie_result = self._real_extract(url)
  File "/home/cynthia/Public/hanime-plugin/yt_dlp_plugins/extractor/hanime1.py", line 83, in _real_extract
    webpage = self._download_webpage(url, video_id)
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/extractor/common.py", line 1202, in _download_webpage
    return self.__download_webpage(url_or_request, video_id, note, errnote, None, fatal, *args, **kwargs)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/extractor/common.py", line 1153, in download_content
    res = getattr(self, download_handle.__name__)(url_or_request, video_id, **kwargs)
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/extractor/common.py", line 976, in _download_webpage_handle
    urlh = self._request_webpage(url_or_request, video_id, note, errnote, fatal, data=data,
                                 headers=headers, query=query, expected_status=expected_status,
                                 impersonate=impersonate, require_impersonation=require_impersonation)
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/extractor/common.py", line 925, in _request_webpage
    raise ExtractorError(errmsg, cause=err)

  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/networking/_urllib.py", line 419, in _send
    res = opener.open(urllib_req, timeout=self._calculate_timeout(request))
  File "/usr/lib/python3.14/urllib/request.py", line 493, in open
    response = meth(req, response)
  File "/usr/lib/python3.14/urllib/request.py", line 602, in http_response
    response = self.parent.error(
        'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.14/urllib/request.py", line 531, in error
    return self._call_chain(*args)
           ~~~~~~~~~~~~~~~~^^^^^^^
  File "/usr/lib/python3.14/urllib/request.py", line 464, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.14/urllib/request.py", line 611, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

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

Traceback (most recent call last):
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/extractor/common.py", line 912, in _request_webpage
    return self._downloader.urlopen(self._create_request(url_or_request, data, headers, query, extensions))
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/YoutubeDL.py", line 4260, in urlopen
    return self._request_director.send(req)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/networking/common.py", line 117, in send
    response = handler.send(request)
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/networking/_helper.py", line 194, in wrapper
    return func(self, *args, **kwargs)
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/networking/common.py", line 359, in send
    return self._send(request)
           ~~~~~~~~~~^^^^^^^^^
  File "/home/cynthia/Public/hanime-plugin/.venv/lib/python3.14/site-packages/yt_dlp/networking/_urllib.py", line 424, in _send
    raise HTTPError(UrllibResponseAdapter(e.fp), redirect_loop='redirect error' in str(e)) from e
yt_dlp.networking.exceptions.HTTPError: HTTP Error 403: Forbidden

@cynthia2006

Copy link
Copy Markdown
Owner

Hmm, I tried --impersonate and --cookies as well, but it didn't work for some reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants