yt-dlp: spankbang - 403 Forbidden errors

DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

  • I understand that I will be blocked if I intentionally remove or skip any mandatory* field

Checklist

Region

USA

Provide a description that is worded well enough to be understood

All video url’s from Spankbang are returning 403 forbidden errors. I have confirmed that they load and play in the browser just fine. Verbose output is provided. My yt-dlp version is completely up to date.

Provide verbose output that clearly demonstrates the problem

  • Run your yt-dlp command with -vU flag added (yt-dlp -vU <your command line>)
  • If using API, add 'verbose': True to YoutubeDL params instead
  • Copy the WHOLE output (starting with [debug] Command-line config) and insert it below

Complete Verbose Output

> yt-dlp -vU https://spankbang.com/6c6z5/video/fan+appreciation+event+english+sub
[debug] Command-line config: ['-vU', 'https://spankbang.com/6c6z5/video/fan+appreciation+event+english+sub']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, err utf-8, pref UTF-8
[debug] yt-dlp version 2022.02.04 [c1653e9ef] (zip)
[debug] Python version 3.8.10 (CPython 64bit) - Linux-4.4.0-19041-Microsoft-x86_64-with-glibc2.29
[debug] exe versions: ffmpeg 4.2.4, ffprobe 4.2.4
[debug] Optional libraries: Cryptodome, secretstorage, mutagen, sqlite, websockets
[debug] Proxy map: {}
Latest version: 2023.03.04, Current version: 2022.02.04
Current Build Hash a16fe3b3bd474d562c4b8645579b209377b967d58d4edffe6e31dc8de81d7283
Updating to version 2023.03.04 ...
ERROR: Unable to write to /usr/local/bin/yt-dlp; Try running as administrator
[debug] [SpankBang] Extracting URL: https://spankbang.com/6c6z5/video/fan+appreciation+event+english+sub
[SpankBang] 6c6z5: Downloading webpage
ERROR: [SpankBang] 6c6z5: Unable to download webpage: HTTP Error 403: Forbidden (caused by <HTTPError 403: 'Forbidden'>); please report this issue on  https://github.com/yt-dlp/yt-dlp , filling out the "Broken site" issue template properly. Confirm you are on the latest version using -U (caused by <HTTPError 403: 'Forbidden'>); please report this issue on  https://github.com/yt-dlp/yt-dlp , filling out the "Broken site" issue template properly. Confirm you are on the latest version using -U
  File "/usr/local/bin/yt-dlp/yt_dlp/extractor/common.py", line 730, in _request_webpage
    return self._downloader.urlopen(url_or_request)
  File "/usr/local/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 3558, in urlopen    return self._opener.open(req, timeout=self._socket_timeout)  File "/usr/lib/python3.8/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/usr/lib/python3.8/urllib/request.py", line 640, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.8/urllib/request.py", line 569, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.8/urllib/request.py", line 649, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Comments: 42 (12 by maintainers)

Most upvoted comments

workaround: try adding --legacy-server-connect to your command

One workaround I found is working perfectly.

Just change the URL from https://spankbang.com/5icow/video/skylarvox08 to https://spankbang.party/5icow/video/skylarvox08

Domain part from spankbang.com to spankbang.party works perfectly for all URLs I tested.

I’ve noticed yt-dlp using TLSv1_2 while the web browser uses TLSv1_3.

You can temporarily add TLSv1_3 in yt_dlp/networking/_helper.py (note that this affects all requests, of course):


#context.minimum_version = ssl.TLSVersion.TLSv1_2
context.minimum_version = ssl.TLSVersion.TLSv1_3

Similar issue #25437

I’ve noticed yt-dlp using TLSv1_2 while the web browser uses TLSv1_3.

You can temporarily add TLSv1_3 in yt_dlp/networking/_helper.py (note that this affects all requests, of course):


#context.minimum_version = ssl.TLSVersion.TLSv1_2
context.minimum_version = ssl.TLSVersion.TLSv1_3

Similar issue #25437

This worked for me. I think this library (_helper.py) is too global to change that value for the whole project, but it would be nice if specific extractors/downloaders could set that value to workaround this issue.

@dirkf any plans to submit a PR? I would assume that it would be within scope to automatically use spankbang.party’s server, unless that’s an unofficial mirror, which I highly doubt

adding --legacy-server-connect to my config file

don’t do this. only use this option when needed

The .party and .com domains are both registered via NameCheap from Capital Region (Reykjavik, apparently)

that doesn’t necessarily mean anything, that’s just namecheap’s whois privacy thing Screenshot 2023-10-09 at 15-53-29 Domain Screenshot 2023-10-09 at 15-53-40 Domain

seems to work with the party server but it doesn’t work with playlist links

Isn’t the HTML5 format 4 found by the generic extractor 4320x2160 (actually 2x2160x2160 since this video is 3D)?

If the SB extractor is tweaked to recognise .party and to use that root domain for its stream JSON retrieval:

$ yt-dlp -v -F 'https://spankbang.party/5icow/video/skylarvox08'
[debug] Command-line config: ['-v', '-F', 'https://spankbang.party/5icow/video/skylarvox08']
[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@2023.06.22 [812cdfa06] (source)
[debug] Lazy loading extractors is disabled
[debug] Git HEAD: de4cf77ec
[debug] Python 3.9.16 (CPython i686 32bit) - Linux-4.4.0-210-generic-i686-with-glibc2.23 (OpenSSL 1.1.1v  1 Aug 2023, glibc 2.23)
[debug] exe versions: ffmpeg 4.3, ffprobe 4.3
[debug] Optional libraries: Cryptodome-3.11.0, certifi-2019.11.28, secretstorage-3.2.0, sqlite3-2.6.0
[debug] Proxy map: {}
[debug] Loaded 1851 extractors
[SpankBang] Extracting URL: https://spankbang.party/5icow/video/skylarvox08
[SpankBang] 5icow: Downloading webpage
[SpankBang] 5icow: Downloading stream JSON
[SpankBang] 5icow: Downloading m3u8 information
[SpankBang] 5icow: Downloading m3u8 information
[SpankBang] 5icow: Downloading m3u8 information
[SpankBang] 5icow: Downloading m3u8 information
[SpankBang] 5icow: Downloading m3u8 information
[SpankBang] 5icow: Downloading m3u8 information
[debug] Formats sorted by: hasvid, ie_pref, lang, quality, res, fps, hdr:12(7), vcodec:vp9.2(10), channels, acodec, size, br, asr, proto, vext, aext, hasaud, source, id
[info] Available formats for 5icow:
ID         EXT RESOLUTION FPS │   FILESIZE   TBR PROTO │ VCODEC      ACODEC
──────────────────────────────────────────────────────────────────────────────
240p       mp4 240p           │                  https │ unknown     unknown
hls-231-0  mp4 480x240     30 │ ~ 60.42MiB  231k m3u8  │ avc1.42c01e mp4a.40.2
hls-231-1  mp4 480x240     30 │ ~ 60.42MiB  231k m3u8  │ avc1.42c01e mp4a.40.2
480p       mp4 480p           │                  https │ unknown     unknown
hls-1201-0 mp4 960x480     30 │ ~314.06MiB 1202k m3u8  │ avc1.4d401f mp4a.40.2
hls-1201-1 mp4 960x480     30 │ ~314.06MiB 1202k m3u8  │ avc1.4d401f mp4a.40.2
720p       mp4 720p           │                  https │ unknown     unknown
hls-2172-0 mp4 1440x720    30 │ ~567.77MiB 2172k m3u8  │ avc1.640020 mp4a.40.2
hls-2172-1 mp4 1440x720    30 │ ~567.77MiB 2172k m3u8  │ avc1.640020 mp4a.40.2
1080p      mp4 1080p          │                  https │ unknown     unknown
hls-3390-0 mp4 2160x1080   30 │ ~886.07MiB 3390k m3u8  │ avc1.64002a mp4a.40.2
hls-3390-1 mp4 2160x1080   30 │ ~886.07MiB 3390k m3u8  │ avc1.64002a mp4a.40.2
4k         mp4 2160p          │                  https │ unknown     unknown
hls-5543-0 mp4 4320x2160   30 │ ~  1.41GiB 5543k m3u8  │ avc1.640034 mp4a.40.2
hls-5543-1 mp4 4320x2160   30 │ ~  1.41GiB 5543k m3u8  │ avc1.640034 mp4a.40.2
$

#7595, once completed, should fix this

adding --legacy-server-connect to my config file

don’t do this. only use this option when needed

good call. created separate config and batch to call that option if needed.

In my case, 'Cookie': 'country=US' in _real_extract of extractor/spankbang.py needs to be manually replaced with the Cookie header. Note that setting the user-agent will cause a 403 error, even after replacing 'Cookie': 'country=US'. Additionally, the cookie must be added to the self._download_json() method. Also, the cookie needs to be renewed after it expires.

can you go into greater detail please?

Simply right-click on video web page - >“Inspect” -> “Network” tab -> click upper left “Clear” button -> Ctrl+R Reload page -> click current page url item(normally first item or it has blue icon on left side) -> right panel -> “Headers” tab -> “Requests Headers” section), copy Cookie’s value(and copy User-Agent’s value later) and paste into the below 4 Lines to replace: in the file extractor/spankbang.py ( you can find parent folder of extractor/spankbang.py with command python3 -c "import yt_dlp; print(yt_dlp.__path__[0])" ). -> save the edited file -> rerun yt-dlp should no more 403 error.

4 Lines to edit:

[1] Add this line MY_COOKIE = on top of line class SpankBangIE(InfoExtractor): with your copied cookie value, you only need to edit this line in future when renew cookie, e.g.:


MY_COOKIE = 'paste your copied cookie value, surrounded with single quotes. No extra space'

class SpankBangIE(InfoExtractor):

[2] url, playlist_id, headers={'Cookie': 'country=US; mobile=on'})

edit it to:

url, playlist_id, headers={'Cookie': MY_COOKIE})

and:

[3] video_id, headers={'Cookie': 'country=US'})

edit it to:

video_id, headers={'Cookie': MY_COOKIE})

[4] Then under self._download_json need add cookie too, e.g.:

                }), headers={
                    'Referer': url,
                    'X-Requested-With': 'XMLHttpRequest',
                })

edit it to:

                   }), headers={
                    'Cookie': MY_COOKIE,
                    'Referer': url,
                    'X-Requested-With': 'XMLHttpRequest',
                })

Note that the spaces before the lines need typing space instead of tab. And ensure total spaces same as original.

Note that the cookie needs renewal after it expires or the IP changes. You may need clear and reload page if first attempt of cookie not working. Ensure copy the complete cookie value. Update yt-dlp may replace this code and need redo.

You also need add your copied latest User-Agent’s value(same steps as get Cookie’s value. It probably updated when web browser update) to your command, e.g. --add-headers 'User-Agent:paste your copied user-agent value, surrounded with single quotes':

yt-dlp --add-headers 'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' ...

Note that you need to use user agent get from the same web browser of the cookie above.

In my case, 'Cookie': 'country=US' in _real_extract of extractor/spankbang.py needs to be manually replaced with the Cookie header. Note that setting the user-agent will cause a 403 error, even after replacing 'Cookie': 'country=US'. Additionally, the cookie must be added to the self._download_json() method. Also, the cookie needs to be renewed after it expires.

yt-dlp stable@2023.03.04 isn’t showing 403 for me with 81sy6, but yt-dl (essentially identical extractor code) is getting 403 on the webpage itself, as is is wget, not showing any page content in the response. UA ‘Mozilla/5.0’ may break through CloudFlare: it works with yt-dl and wget now, though not when I first tried.