【发布时间】:2023-03-20 20:01:01
【问题描述】:
从一个页面加载 Facebook 提要时,如果提要中存在图片,我想显示大图。
如何使用 graph API ?提要中的图片链接不大。
谢谢。
【问题讨论】:
-
当前答案不再有效。请更新您选择的答案。 @Benjamin Kuijten 现在有了正确的答案。
从一个页面加载 Facebook 提要时,如果提要中存在图片,我想显示大图。
如何使用 graph API ?提要中的图片链接不大。
谢谢。
【问题讨论】:
Graph API photo object 有一个picture 连接(类似于用户对象有):
“相册大小的照片视图。 […] 返回:HTTP 302 重定向到图片的 URL。”
因此,请求 https://graph.facebook.com/{object-id-from-feed}/picture 会立即将您重定向到相册大小的照片版本。 (不仅对于在浏览器中显示它很有用,而且如果您想将图像下载到您的服务器,使用带有 follow_redirect 选项集的 cURL。)
编辑:
从 API v2.3 开始,供稿帖子的 /picture 边缘已弃用。
然而,作为一个字段,图片仍然可以被请求——但它会很小。
但full_picture 也可用。
所以/{object-id-from-feed}?fields=picture,full_picture 可以用来请求这些,或者它们可以直接与其余的提要数据一起请求,例如/page-id/feed?fields=picture,full_picture,…(其他字段,例如消息等,必须以相同的方式指定。)
【讨论】:
full_picture 参数
什么对我有用:
从提要中获取图片链接并将“_s.jpg”替换为“_n.jpg”
【讨论】:
"(#100) No node specified" 的OAuthException。
好的,我找到了更好的方法。当您使用图形 API 检索提要时,任何类型为 photo 的提要项目都会有一个名为 object_id 的字段,而对于普通的 status 类型的项目则不存在该字段。使用该 ID 查询 Graph API,例如https://graph.facebook.com/1234567890。请注意,对象 ID 不是像该提要项的主 ID 那样的下划线分隔值。
object_id 查询的结果将是一个新的 JSON 字典,其中您将有一个 source 属性,其中包含一个图像的 URL,该图像到目前为止已经足够满足我的需要。
另外还有一个images 数组,其中包含更多不同尺寸图像的图像 URL,但那里的尺寸似乎无法预测,并且实际上并不都对应于背后图像的物理尺寸那个网址。
我仍然希望有一种方法可以通过单个 Graph API 调用来做到这一点,但看起来好像没有。
【讨论】:
高分辨率图片链接来自:
我使用以下:
注意:我给予_s -> _o hack 优先于object_id/picture 方法的原因是因为object_id 方法没有返回所有图像的结果。
var picture = result.picture;
if (picture) {
if (result.type === 'photo') {
if (picture.indexOf('_s') !== -1) {
console.log('CONVERTING');
picture = picture.replace(/_s/, '_o');
} else if (result.object_id) {
picture = 'https://graph.facebook.com/' + result.object_id + '/picture?width=9999&height=9999';
}
} else {
var qps = result.picture.split('&');
for (var i = 0; i < qps.length; i++) {
var qp = qps[i];
var matches = qp.match(/(url=|src=)/gi);
if (matches && matches.length > 0) picture = decodeURIComponent(qp.split(matches[0])[1]);
}
}
}
【讨论】:
_n.jpg 或_n.png 结束。不需要更换那些。相反,您必须摆脱 /p130x130 或 /s130x130。
这是一种获取大图像的新方法。它是在预览方法不起作用后诞生的
/**
* return a big url of facebook
* works onky for type PHOTO
* @param picture
* @param is a post type link
* @return url of image
*/
@Transactional
public String getBigImageByFacebookPicture(String pictrue,Boolean link){
if(link && pictrue.contains("url=http")){
String url = pictrue.substring(pictrue.indexOf("url=") + 4);
try {
url = java.net.URLDecoder.decode(url, "UTF-8");
} catch (UnsupportedEncodingException e) {
StringBuffer sb = new StringBuffer("Big image for Facebook link not found: ");
sb.append(link);
loggerTakePost.error(sb.toString());
return null;
}
return url;
}else{
try {
Document doc = Jsoup.connect(pictrue).get();
return doc.select("#fbPhotoImage").get(0).attr("src");
} catch (Exception e) {
StringBuffer sb = new StringBuffer("Big image for Facebook link not found: ");
sb.append(link);
loggerTakePost.error(sb.toString());
return null;
}
}
}
享受您的大图 :)
【讨论】:
实际上,您需要两种不同的解决方案才能完全解决此问题。
1]https://graph.facebook.com/{object_id}/图片
此解决方案适用于发布到 Facebook 的图像和视频,但遗憾的是,如果原始图像文件未直接上传到 Facebook,它会返回小图像。 (例如,在您的页面上发布指向另一个网站的链接时)。
2] Facebook Graph API 提供了一种方法来获取这些外部链接的供稿本身的完整图像。如果您在调用 API 时将“full_picture”添加到如下示例中的字段,则会为您提供更高分辨率版本的链接。
结合这两种解决方案,我最终过滤了 PHP 中的输入,如下所示:
if ( isset( $post['object_id'] ) ){
$image_url = 'https://graph.facebook.com/'.$post['object_id'].'/picture';
}else if ( isset( $post['full_picture'] ) ) {
$image_url = $post['full_picture'];
}else{
$image_url = '';
}
【讨论】:
见:http://api-portal.anypoint.mulesoft.com/facebook/api/facebook-graph-api/docs/reference/pictures
只需在 URL 后加上“?type=large”即可获得大图。
【讨论】:
感谢 @mattdlockyer 的 JS 解决方案。这是 PHP 中类似的东西:
$posts = $facebook->api('/[page]/posts/', 'get');
foreach($posts['data'] as $post)
{
if(stristr(@$post['picture'], '_s.'))
{
$post['picture'] = str_replace('_s.', '_n.', @$post['picture']);
}
if(stristr(@$post['picture'], 'url='))
{
parse_str($post['picture'], $picturearr);
if($picturearr['url'])
$post['picture'] = $picturearr['url'];
}
//do more stuff with $post and $post['picture'] ...
}
【讨论】:
在得到@Lachezar Todorov 的积极评价后,我决定发布我目前的方法(包括分页和使用Json.NET;):
try
{
FacebookClient fbClient = new FacebookClient(HttpContext.Current.Session[SessionFacebookAccessToken].ToString());
JObject posts = JObject.Parse(fbClient.Get(String.Format("/{0}/posts?fields=message,picture,link,attachments", FacebookPageId)).ToString());
JArray newsItems = (JArray)posts["data"];
List<NewsItem> result = new List<NewsItem>();
while (newsItems.Count > 0)
{
result.AddRange(GetItemsFromJsonData(newsItems));
if (result.Count > MaxNewsItems)
{
result.RemoveRange(MaxNewsItems, result.Count - MaxNewsItems);
break;
}
JToken paging = posts["paging"];
if (paging != null)
{
if (paging["next"] != null)
{
posts = JObject.Parse(fbClient.Get(paging.Value<String>("next")).ToString());
newsItems = (JArray)posts["data"];
}
}
}
return result;
}
以及检索单个项目的辅助方法:
private static IEnumerable<NewsItem> GetItemsFromJsonData(IEnumerable<JToken> items)
{
List<NewsItem> newsItems = new List<NewsItem>();
foreach (JToken item in items.Where(item => item["message"] != null))
{
NewsItem ni = new NewsItem
{
Message = item.Value<String>("message"),
DateTimeCreation = item.Value<DateTime?>("created_time"),
Link = item.Value<String>("link"),
Thumbnail = item.Value<String>("picture"),
// http://stackoverflow.com/questions/28319242/simplify-looking-up-nested-json-values-with-json-net/28359155#28359155
Image = (String)item.SelectToken("attachments.data[0].media.image.src") ?? (String)item.SelectToken("attachments.data[0].subattachments.data[0].media.image.src")
};
newsItems.Add(ni);
}
return newsItems;
}
我使用的 NewsItem 类:
public class NewsItem
{
public String Message { get; set; }
public DateTime? DateTimeCreation { get; set; }
public String Link { get; set; }
public String Thumbnail { get; set; }
public String Image { get; set; }
}
【讨论】: