[facebook] add initial 'albums' extractor (#7848)

needs GraphQL API to fetch more than the latest 8
This commit is contained in:
Mike Fährmann
2025-08-08 18:14:21 +02:00
parent 8ada5b8eb6
commit 2192a2c360
4 changed files with 53 additions and 2 deletions

View File

@@ -2680,6 +2680,7 @@ Description
* ``avatar`` * ``avatar``
* ``photos`` * ``photos``
* ``albums``
It is possible to use ``"all"`` instead of listing all values separately. It is possible to use ``"all"`` instead of listing all values separately.

View File

@@ -280,7 +280,7 @@ Consider all listed sites to potentially be NSFW.
<tr> <tr>
<td>Facebook</td> <td>Facebook</td>
<td>https://www.facebook.com/</td> <td>https://www.facebook.com/</td>
<td>Avatars, Photos, Profile Photos, Sets, User Profiles, Videos</td> <td>Albums, Avatars, Photos, Profile Photos, Sets, User Profiles, Videos</td>
<td><a href="https://github.com/mikf/gallery-dl#cookies">Cookies</a></td> <td><a href="https://github.com/mikf/gallery-dl#cookies">Cookies</a></td>
</tr> </tr>
<tr> <tr>

View File

@@ -7,7 +7,7 @@
"""Extractors for https://www.facebook.com/""" """Extractors for https://www.facebook.com/"""
from .common import Extractor, Message, Dispatch from .common import Extractor, Message, Dispatch
from .. import text, exception from .. import text, util, exception
from ..cache import memcache from ..cache import memcache
BASE_PATTERN = r"(?:https?://)?(?:[\w-]+\.)?facebook\.com" BASE_PATTERN = r"(?:https?://)?(?:[\w-]+\.)?facebook\.com"
@@ -440,6 +440,34 @@ class FacebookVideoExtractor(FacebookExtractor):
yield Message.Url, audio["url"], audio yield Message.Url, audio["url"], audio
class FacebookAlbumsExtractor(FacebookExtractor):
"""Extractor for Facebook Profile albums"""
subcategory = "albums"
pattern = USER_PATTERN + r"/photos_albums"
example = "https://www.facebook.com/USERNAME/photos_albums"
def items(self):
url = f"{self.root}/{self.groups[0]}/photos_albums"
page = self.request(url).text
pos = page.find(
'"TimelineAppCollectionAlbumsRenderer","collection":{"id":"')
if pos < 0:
return
items = text.extract(page, '},"pageItems":', '}}},', pos)[0]
edges = util.json_loads(items + "}}")["edges"]
# TODO: use /graphql API endpoint
for edge in edges:
node = edge["node"]
album = node["node"]
album["_extractor"] = FacebookSetExtractor
album["title"] = node["title"]["text"]
album["thumbnail"] = (img := node["image"]) and img["uri"]
yield Message.Queue, album["url"], album
class FacebookPhotosExtractor(FacebookExtractor): class FacebookPhotosExtractor(FacebookExtractor):
"""Extractor for Facebook Profile Photos""" """Extractor for Facebook Profile Photos"""
subcategory = "photos" subcategory = "photos"
@@ -489,4 +517,5 @@ class FacebookUserExtractor(Dispatch, FacebookExtractor):
return self._dispatch_extractors(( return self._dispatch_extractors((
(FacebookAvatarExtractor, base + "avatar"), (FacebookAvatarExtractor, base + "avatar"),
(FacebookPhotosExtractor, base + "photos"), (FacebookPhotosExtractor, base + "photos"),
(FacebookAlbumsExtractor, base + "photos_albums"),
), ("photos",)) ), ("photos",))

View File

@@ -244,4 +244,25 @@ __tests__ = (
"username" : "Facebook", "username" : "Facebook",
}, },
{
"#url" : "https://www.facebook.com/facebook/photos_albums",
"#class" : facebook.FacebookAlbumsExtractor,
"#pattern" : facebook.FacebookSetExtractor.pattern,
"#results" : [
"https://www.facebook.com/media/set/?set=a.736550598516963&type=3",
"https://www.facebook.com/media/set/?set=a.736550611850295&type=3",
"https://www.facebook.com/media/set/?set=a.1198986285606723&type=3",
"https://www.facebook.com/media/set/?set=a.1188430493328969&type=3",
"https://www.facebook.com/media/set/?set=a.1182920610546624&type=3",
"https://www.facebook.com/media/set/?set=a.1152503723588313&type=3",
"https://www.facebook.com/media/set/?set=a.912647394240615&type=3",
"https://www.facebook.com/media/set/?set=a.862611645910857&type=3",
],
"id" : r"re:\d+",
"thumbnail": {str, None},
"title" : str,
"url" : str,
},
) )