Размещение фотографий из Facebook на сайте

в 16:08, , рубрики: .net, ASP, ASP.NET, Facebook, ONE ☆ LIFE, web-разработка, Веб-разработка, метки: , , , ,

Размещение фотографий из Facebook на сайте

Добрый день!
Хочу поделится методом интеграции альбомов Facebook в сайт.

Метод реализован на C# с использованием Linq, однако основная логика работы находится в регулярных выражениях и легко может быть воспроизведена на любом другом языке программирования.

Предыстория, или с чего все началось

А началось все с разработки ресурса для сообщества путешественников, любителей жизни, да и просто замечательных людей — ONE ☆ LIFE.

На момент начала разработки у сообщества было уже несколько тысяч фотографий в альбомах Facebook-группы. Поскольку дублировать все фотографии на сайт не рационально, а необходимость иллюстрировать события и публикации на сайте возникает достаточно часто — было решено сделать возможность импорта фотографий на сайт сообщества.

Такой подход помимо упрощения работы контент-менеджеру (ему не придется загружать фотографии на несколько ресурсов одновременно) также позволяет снять часть за счет того, что фотографии будут загружаться с CDN сети Facebook. Так же, в перспективе это позволит ванлайферам самим делиться своими фото используя свои альбомы в Facebook.
О том как это было сделано — рассказано ниже.

Суть задачи и ее решение

Изначально Facebook предлагает возможность поделится своими альбомами с незарегистрированными пользователями по специальной ссылке которая находится внизу под списком фотографий:

Размещение фотографий из Facebook на сайте

Альбомы групп практически всегда доступны по прямой ссылке которую можно получить просто зайдя в альбом и скопировав url из адресной строки. Именно по этим ссылкам и будет производится разбор альбомов.

К сожалению у Facebook нет публичного rss представления для альбома, поэтому разбирать придется достаточно запутанный и громоздкий код. (Хотя как позже оказалось — запутанный и громоздкий он только на первый взгляд, на самом деле он достаточно хорошо поддается разбору).

Для интереса рекомендую посмотреть исходный код любого альбома что бы понимать с чем именно придется иметь дело.

Там вы увидите огромное количество html кода. Часть из которого закоментированна:
Размещение фотографий из Facebook на сайте

Но как оказалось — именно в этом закоментированном коде и находится необходимая информация об альбоме, которая после загрузки страницы в браузер обрабатывается джава-скриптом.

Так же стоит обратить внимание на то, что запрос должен общаться с хедером, соответствующим одному из современных бразуреов, иначе можете вместо альбома получить страницу с сообщением, что ваш браузер не поддерживает джаваскрипт.

На данный момент мною реализован метод разбора, который позволяет получить название альбома, список полноразмерных фотографий и их preview.

public static Album LoadFromFacebook(string albumPublicLink)
        {
            var webClient = new WebClient();
            webClient.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.2; .NET CLR 4.0;)");
            webClient.Encoding = Encoding.UTF8;
            var html = webClient.DownloadString(albumPublicLink);

            var title = Regex.Match(html, "<title>(.*)</title>").Value; //Album title

            var photoList = new List<String>();
            var resultList2 = new List<String>();
            var resultList3 = new List<String>();

            var regexObj1 = new Regex(@"(&src=(?<url>(.*?))s*_(n|o).jpg)");   //Big  photos
            var regexObj2 = new Regex(@"(data-src=""(?<url>(.*?))s*_a.jpg)");     //Preview
            var regexObj3 = new Regex(@"<i style=""background-image: url((?<url>(.*?)jpg));""></i>");     //Preview

            var matchResult1 = regexObj1.Match(html);
            var matchResult2 = regexObj2.Match(html);
            var matchResult3 = regexObj3.Match(html);

            while (matchResult1.Success)
            {
                var link = HttpUtility.UrlDecode(matchResult1.Value.Replace("&src=", String.Empty));
                photoList.Add(link);
                matchResult1 = matchResult1.NextMatch();
            }

            while (matchResult2.Success)
            {
                var link = HttpUtility.UrlDecode(matchResult2.Value.Replace("data-src="", String.Empty));
                resultList2.Add(link);
                matchResult2 = matchResult2.NextMatch();
            }

            while (matchResult3.Success)
            {
                var link = HttpUtility.UrlDecode(matchResult3.Value.Replace("<i style="background-image: url(", String.Empty)).Replace(");"></i>", String.Empty).Trim();
                resultList3.Add(link);
                matchResult3 = matchResult3.NextMatch();
            }

            var previewList = new List<string>(); //List for merged preview array
            previewList.AddRange(resultList2);
            previewList.AddRange(resultList3);
            
            var photos = new List<Photo>();

            for (int i = 0; i < photoList.Count; i++)
            {
                var url = photoList[i];

                //Find file name i.e. 123423_32435_4543
                var resultString = Regex.Match(url, @"/(?<key>(w*))(n|o|a).jpg").Groups["key"].Value;

                //Find preview for big photo
                var previewUrl = (from o in previewList
                                  where Regex.Match(o, @"/(?<key>(w*))(n|o|a).jpg").Groups["key"].Value == resultString
                                  select o).SingleOrDefault();


                photos.Add(new Photo
                               {
                                   PreviewUrl = previewUrl,
                                   Url = url
                               });
            }

            var description = String.Empty;

            var album = new Album(title, description, photos);
            return album;
        }

В дальнейшем планирую я так же добавить возможность вытягивать описания к фото.

Пример реализации

Посмотреть что из этого получилось можно тут:

Размещение фотографий из Facebook на сайте

Код примера можно скачать тут.

В примерах использовались фотографии из альбома Артемия Сурина — основателя движения One Star Life.

Автор: Ernado


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js