Files

49 lines
1.7 KiB
Python

import sys
import re
from pathlib import Path
# Add parent workspace directory to path to import generic_downloader
sys.path.append(str(Path(__file__).resolve().parents[1]))
import generic_downloader
def is_video_link(url):
# Match standard xHamster video pages: contains /videos/ and doesn't point to user grids/channels
return (
"/videos/" in url
and not "/users/" in url
and not "/channels/" in url
and not "/creators/" in url
)
if __name__ == "__main__":
# JS evaluated in browser context to get the clean uploader name
uploader_eval = """() => {
// 1. Try channel link
const channelLink = document.querySelector('a[href*="/channels/"]');
if (channelLink && channelLink.innerText.trim()) {
return channelLink.innerText.trim().replace(/\\n/g, ' ').trim();
}
// 2. Try user link
const userLink = document.querySelector('.entity-author-container__name, a[href*="/users/"]');
if (userLink && userLink.innerText.trim()) {
return userLink.innerText.trim();
}
// 3. Try creator logo or class
const creatorLink = document.querySelector('a[href*="/creators/"] .video-uploader__name, .video-uploader__name');
if (creatorLink && creatorLink.innerText.trim()) {
return creatorLink.innerText.trim();
}
return 'unknown';
}"""
generic_downloader.run(
site_name="xHamster",
is_video_link_fn=is_video_link,
next_page_selector="a:has-text('Next'), .next, a[rel='next']",
video_selector="video",
uploader_eval_js=uploader_eval
)