baptx

facebook_friends_people_search_backup

Feb 4th, 2020 (edited)
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Facebook friends / people search / group members backup in web browser
  2.  * Scroll down to your friends page or a people search page to load all profiles
  3.  * Copy-paste the script below in a web browser console (F12 key or Ctrl+Shift+K shortcut in a browser like Firefox) and execute the desired function, for example by typing FacebookFriendsBackup() in the console and pressing enter
  4.  * A textarea will appear at the end of the page so you can copy the data and paste it in a text file before saving it as a CSV file
  5.  * You can then view your backup in a spreadsheet editor like LibreOffice Calc
  6.  * You can also compare the backup with another one to see who removed you from their friends list or who appeared in a new search (e.g. with the Linux diff command or awk for column diff https://unix.stackexchange.com/questions/174599/using-diff-on-a-specific-column-in-a-file/174603#174603)
  7.  * If the friend changed their name or profile URL, you can still find them with their profile ID which is backed up in the last column (open facebook.com/PROFILE_ID in a web browser)
  8.  * The Facebook Graph API was not used because they are locking or deprecating most of their endpoints (e.g. https://developers.facebook.com/docs/graph-api/changelog/breaking-changes/#taggable-friends-4-4)
  9.  */
  10.  
  11. var data = [];
  12.  
  13. // to make this script work with the new Facebook, you need to open the mobile web version https://m.facebook.com/username/friends
  14. function FacebookFriendsBackup()
  15. {
  16.     var mainList = document.getElementsByClassName("timeline")[0].childNodes[1].childNodes[2].childNodes;
  17.     var mainLength = mainList.length;
  18.    
  19.     for (var i = 0; i < mainLength; ++i) {
  20.         var list = mainList[i].childNodes;
  21.         var length = list.length;
  22.        
  23.         for (var j = 0; j < length; ++j) {
  24.             var link = list[j].getElementsByTagName("a")[1];
  25.             var count = data.length;
  26.             data[count] = link.firstChild.nodeValue;
  27.             data[count] += "\t" + link.href;
  28.             var friendsButton = list[j].firstChild.childNodes[2];
  29.             if (!friendsButton) {
  30.                 friendsButton = list[j].childNodes[2]; // fix for Chromium (for some reason, Facebook generates a different DOM structure with Firefox)
  31.             }
  32.             var json = JSON.parse(friendsButton.firstChild.firstChild.childNodes[2].getAttribute("data-store"));
  33.             data[count] += "\t" + json.id;
  34.         }
  35.     }
  36.    
  37.     displayData();
  38. }
  39.  
  40. // NOT WORKING WITH NEW FACEBOOK (use the updated function above)
  41. function OldFacebookFriendsBackup()
  42. {
  43.     var list = document.getElementsByClassName("uiProfileBlockContent");
  44.     var length = list.length;
  45.  
  46.     // note: firstChild is a bit faster than firstElementChild: https://jsperf.com/firstelementchild-and-firstchild
  47.     for (var i = 0; i < length; ++i) {
  48.         var link = list[i].getElementsByTagName("a")[0];
  49.         data[i] = link.firstChild.nodeValue;
  50.         data[i] += "\t" + link.href;
  51.         var json = JSON.parse(link.getAttribute("data-gt"));
  52.         if (json) { // JSON data is null when the Facebook profile is deactivated
  53.             data[i] += "\t" + json.engagement.eng_tid; // get profile ID in case the Facebook user changes their profile URL
  54.         }
  55.     }
  56.    
  57.     displayData();
  58. }
  59.  
  60. // we need to hook AJAX response with JavaScript to get the profile ID since it is not displayed in the DOM (username is not reliable to backup since it can change)
  61. // execute this function before opening the page and scrolling
  62. // https://stackoverflow.com/questions/5202296/add-a-hook-to-all-ajax-requests-on-a-page/27363569#27363569
  63. function FacebookPeopleSearchBackup()
  64. {
  65.     var count = 0;
  66.  
  67.     var origOpen = XMLHttpRequest.prototype.open;
  68.     XMLHttpRequest.prototype.open = function() {
  69.         if (arguments[1] == "/api/graphql/") {
  70.             this.addEventListener("load", function() {
  71.                 var json = JSON.parse(this.responseText);
  72.                 var list = json.data.serpResponse.results.edges;
  73.                 var length = list.length;
  74.                
  75.                 for (var i = 0; i < length; ++i) {
  76.                     var user = list[i].relay_rendering_strategy.view_model.profile;
  77.                    
  78.                     if (user) {
  79.                         data[count] = user.id;
  80.                        
  81.                         // comment previous line and uncomment following lines if you want full name and profile URL also
  82.                         /*data[count] = user.name;
  83.                         data[count] += "\t" + user.url;
  84.                         data[count] += "\t" + user.id;*/
  85.                        
  86.                         console.log(data[count]);
  87.                         ++count;
  88.                     }
  89.                     else {
  90.                         console.log("END");
  91.                         displayData();
  92.                     }
  93.                 }
  94.             });
  95.         }
  96.         origOpen.apply(this, arguments);
  97.     };
  98. }
  99.  
  100. // NOT WORKING WITH NEW FACEBOOK (use the updated function above)
  101. // can be used to backup a people search (for example to see when someone from another country or city moves to a new city)
  102. // note: I probably should not have shared the example in parentheses above because it is not working anymore ("the quieter you become, the more you are able to hear")
  103. // some results could be missing since sometimes the city name is followed by the region instead of the country
  104. function OldFacebookPeopleSearchBackup()
  105. {
  106.     //var list = document.getElementById("browse_result_area").getElementsByClassName("FriendRequestOutgoing"); // missing results since friend button is disabled on some profiles
  107.     var list = document.querySelectorAll('#BrowseResultsContainer > div, [data-testid="results"] > div');
  108.     var length = list.length;
  109.    
  110.     for (var i = 0; i < length; ++i) {
  111.         data[i] = JSON.parse(list[i].firstChild.getAttribute("data-bt")).id;
  112.        
  113.         // comment previous line and uncomment following lines if you want full name and profile URL also
  114.         /*var link = list[i].getElementsByTagName("a")[1];
  115.         data[i] = link.title;
  116.         data[i] += "\t" + link.href;
  117.         data[i] += "\t" + JSON.parse(list[i].firstChild.getAttribute("data-bt")).id;*/
  118.     }
  119.    
  120.     displayData();
  121. }
  122.  
  123. // can be used to backup group members with things in common (https://www.facebook.com/groups/XXX/members/things_in_common) or all members
  124. function FacebookGroupMembersBackup()
  125. {
  126.     // use XPath since there is no identifier, only random class names
  127.     var xpath = "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[4]/div/div/div/div/div/div/div/div[2]/div[1]/div/div[2]/div"; // members with things in common
  128.     //var xpath = "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[4]/div/div/div/div/div/div/div/div/div/div/div[2]/div[10]/div/div[2]/div"; // all members
  129.    
  130.     var list = $x(xpath)[0].childNodes;
  131.     var length = list.length;
  132.    
  133.     for (var i = 0; i < length; ++i) {
  134.         var link = list[i].getElementsByTagName("a")[1];
  135.         var split = link.href.split("/");
  136.        
  137.         data[i] = split[split.length - 2];
  138.        
  139.         // comment previous line and uncomment following lines if you want full name also
  140.         /*data[i] = link.firstChild.nodeValue;
  141.         data[i] += "\t" + split[split.length - 2];*/
  142.     }
  143.    
  144.     displayData();
  145. }
  146.  
  147. // NOT WORKING WITH NEW FACEBOOK (use the updated function above)
  148. // can be used to backup group members with things in common (old URL: https://www.facebook.com/groups/XXX/members_with_things_in_common/)
  149. // some results could be missing since sometimes the city uses the original name instead of the translated name
  150. function OldFacebookGroupMembersBackup()
  151. {
  152.     var list = document.querySelectorAll("[id^=things_in_common_]"); // members with things in common
  153.     var length = list.length;
  154.    
  155.     for (var i = 0; i < length; ++i) {
  156.         data[i] = list[i].id.substr(17);
  157.        
  158.         // comment previous line and uncomment following lines if you want full name and profile URL also
  159.         /*var link = list[i].getElementsByTagName("a")[1];
  160.         data[i] = link.title;
  161.         data[i] += "\t" + link.href;
  162.         data[i] += "\t" + list[i].id.substr(17);*/
  163.     }
  164.    
  165.     displayData();
  166. }
  167.  
  168. function displayData()
  169. {
  170.     var box = document.createElement("textarea");
  171.     box.style = "position: relative; z-index: 1"; // show box on top of other elements (needed for the new Facebook with FacebookPeopleSearchBackup())
  172.     box.value = data.join('\n');
  173.     document.body.appendChild(box);
  174. }
  175.  
Add Comment
Please, Sign In to add comment