Initial backup: folder structure manifest, tree summary, scraper scripts, and text metadata
This commit is contained in:
commit
f164832dcc
10504 files changed
+2423594
No files matched your search
@@ -0,0 +1,48 @@
|
||||
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
|
||||
)
|
||||
Reference in new issue
Block a user