Script to scrape Facebook group members and export them into a CSV file. This Facebook Group members extractor works in the browser, without installing an extension or using a proxy. Just copy-paste the script into your Chrome console.
Read our step-by-step guide to extract Facebook group members and find their LinkedIn profile
dist/main.min.js
var G=Object.defineProperty,Q=(e,t,n)=>t in e?G(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,M=(e,t,n)=>(Q(e,"symbol"!=typeof t?t+"":t,n),n);function ee(e,t){for(var n="",r=0;r<t.length;r++)n+=function(e){for(var t="",n=0;n<e.length;n++){var r=null===e[n]||"u"<typeof e[n]?"":e[n].toString(),r=(r=e[n]instanceof Date?e[n].toLocaleString():r).replace(/"/g,'""');0<n&&(t+=","),t+=r=0<=r.search(/("|,|n)/g)?'"'+r+'"':r}return t+` `}(t[r]);var i=new Blob([n],{type:"text/csv;charset=utf-8;"}),o=document.createElement("a");void 0!==o.download&&(i=URL.createObjectURL(i),o.setAttribute("href",i),o.setAttribute("download",e),document.body.appendChild(o),o.click(),document.body.removeChild(o))}const _=(t,e)=>e.some(e=>t instanceof e);let P,j;function te(){return P=P||[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction]}function ne(){return j=j||[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey]}const D=new WeakMap,E=new WeakMap,b=new WeakMap;function re(o){var e=new Promise((e,t)=>{const n=()=>{o.removeEventListener("success",r),o.removeEventListener("error",i)},r=()=>{e(h(o.result)),n()},i=()=>{t(o.error),n()};o.addEventListener("success",r),o.addEventListener("error",i)});return b.set(e,o),e}function ie(o){var e;D.has(o)||(e=new Promise((e,t)=>{const n=()=>{o.removeEventListener("complete",r),o.removeEventListener("error",i),o.removeEventListener("abort",i)},r=()=>{e(),n()},i=()=>{t(o.error||new DOMException("AbortError","AbortError")),n()};o.addEventListener("complete",r),o.addEventListener("error",i),o.addEventListener("abort",i)}),D.set(o,e))}let C={get(e,t,n){if(e instanceof IDBTransaction){if("done"===t)return D.get(e);if("store"===t)return n.objectStoreNames[1]?void 0:n.objectStore(n.objectStoreNames[0])}return h(e[t])},set(e,t,n){return e[t]=n,!0},has(e,t){return e instanceof IDBTransaction&&("done"===t||"store"===t)||t in e}};function K(e){C=e(C)}function oe(t){return ne().includes(t)?function(...e){return t.apply(S(this),e),h(this.request)}:function(...e){return h(t.apply(S(this),e))}}function se(e){return"function"==typeof e?oe(e):(e instanceof IDBTransaction&&ie(e),_(e,te())?new Proxy(e,C):e)}function h(e){if(e instanceof IDBRequest)return re(e);if(E.has(e))return E.get(e);var t=se(e);return t!==e&&(E.set(e,t),b.set(t,e)),t}const S=e=>b.get(e);function ae(e,t,{blocked:n,upgrade:r,blocking:i,terminated:o}={}){const s=indexedDB.open(e,t),a=h(s);return r&&s.addEventListener("upgradeneeded",e=>{r(h(s.result),e.oldVersion,e.newVersion,h(s.transaction),e)}),n&&s.addEventListener("blocked",e=>n(e.oldVersion,e.newVersion,e)),a.then(e=>{o&&e.addEventListener("close",()=>o()),i&&e.addEventListener("versionchange",e=>i(e.oldVersion,e.newVersion,e))}).catch(()=>{}),a}const ce=["get","getKey","getAll","getAllKeys","count"],de=["put","add","delete","clear"],I=new Map;function R(e,t){if(e instanceof IDBDatabase&&!(t in e)&&"string"==typeof t){if(I.get(t))return I.get(t);const r=t.replace(/FromIndex$/,""),i=t!==r,o=de.includes(r);return r in(i?IDBIndex:IDBObjectStore).prototype&&(o||ce.includes(r))?(e=async function(e,...t){e=this.transaction(e,o?"readwrite":"readonly");let n=e.store;return i&&(n=n.index(t.shift())),(await Promise.all([n[r](...t),o&&e.done]))[0]},I.set(t,e),e):void 0}}K(r=>({...r,get:(e,t,n)=>R(e,t)||r.get(e,t,n),has:(e,t)=>!!R(e,t)||r.has(e,t)}));const le=["continue","continuePrimaryKey","advance"],V={},B=new WeakMap,U=new WeakMap,ue={get(e,t){if(!le.includes(t))return e[t];let n=V[t];return n=n||(V[t]=function(...e){B.set(this,U.get(this)[t](...e))})}};async function*fe(...e){let t=this;if(t=t instanceof IDBCursor?t:await t.openCursor(...e)){t=t;var n=new Proxy(t,ue);for(U.set(n,t),b.set(n,S(t));t;)yield n,t=await(B.get(n)||t.continue()),B.delete(n)}}function F(e,t){return t===Symbol.asyncIterator&&_(e,[IDBIndex,IDBObjectStore,IDBCursor])||"iterate"===t&&_(e,[IDBIndex,IDBObjectStore])}K(r=>({...r,get(e,t,n){return F(e,t)?fe:r.get(e,t,n)},has(e,t){return F(e,t)||r.has(e,t)}}));var H,f=function(e,s,a,d){return new(a=a||Promise)(function(n,t){function r(e){try{o(d.next(e))}catch(e){t(e)}}function i(e){try{o(d.throw(e))}catch(e){t(e)}}function o(e){var t;e.done?n(e.value):((t=e.value)instanceof a?t:new a(function(e){e(t)})).then(r,i)}o((d=d.apply(e,s||[])).next())})},he=function(e,t){var n={};for(i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)t.indexOf(i[r])<0&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(n[i[r]]=e[i[r]]);return n};class pe{constructor(e){this.name="scrape-storage",this.persistent=!0,this.data=new Map,null!=e&&e.name&&(this.name=e.name),null!=e&&e.persistent&&(this.persistent=e.persistent),this.initDB().then(()=>{}).catch(()=>{this.persistent=!1})}get storageKey(){return"storage-"+this.name}initDB(){return f(this,void 0,void 0,function*(){this.db=yield ae(this.storageKey,6,{upgrade(e,t,n,r){let i;if(t<5)try{e.deleteObjectStore("data")}catch{}(i=e.objectStoreNames.contains("data")?r.objectStore("data"):e.createObjectStore("data",{keyPath:"_id",autoIncrement:!0}))&&!i.indexNames.contains("_createdAt")&&i.createIndex("_createdAt","_createdAt"),i&&!i.indexNames.contains("_groupId")&&i.createIndex("_groupId","_groupId"),i&&!i.indexNames.contains("_pk")&&i.createIndex("_pk","_pk",{unique:!0})}})})}_dbGetElem(e,t){return f(this,void 0,void 0,function*(){if(this.persistent&&this.db)return yield(t=t||this.db.transaction("data","readonly")).store.index("_pk").get(e);throw new Error("DB doesnt exist")})}getElem(e){return f(this,void 0,void 0,function*(){if(this.persistent&&this.db)try{return yield this._dbGetElem(e)}catch(e){console.error(e)}else this.data.get(e)})}_dbSetElem(i,o,s=!1,a,d){return f(this,void 0,void 0,function*(){if(this.persistent&&this.db){let e=!1;const t=(d=d||this.db.transaction("data","readwrite")).store,n=yield t.index("_pk").get(i);if(n)s&&(yield t.put(Object.assign(Object.assign({},n),o)),e=!0);else{const r=Object.assign({_pk:i,_createdAt:new Date},o);a&&(r._groupId=a),yield t.put(r),e=!0}return e}throw new Error("DB doesnt exist")})}addElem(e,t,n=!1,r){return f(this,void 0,void 0,function*(){if(this.persistent&&this.db)try{return yield this._dbSetElem(e,t,n,r)}catch(e){console.error(e)}else this.data.set(e,t);return!0})}addElems(t,o=!1,s){return f(this,void 0,void 0,function*(){if(this.persistent&&this.db){const n=[],r=this.db.transaction("data","readwrite"),i=[];if(t.forEach(([e,t])=>{-1===i.indexOf(e)&&(i.push(e),n.push(this._dbSetElem(e,t,o,s,r)))}),0<n.length){n.push(r.done);const e=yield Promise.all(n);let t=0;return e.forEach(e=>{"boolean"==typeof e&&e&&(t+=1)}),t}return 0}return t.forEach(([e,t])=>{this.addElem(e,t)}),t.length})}deleteFromGroupId(n){return f(this,void 0,void 0,function*(){if(this.persistent&&this.db){let e=0,t=yield this.db.transaction("data","readwrite").store.index("_groupId").openCursor(IDBKeyRange.only(n));for(;t;)t.delete(),t=yield t.continue(),e+=1;return e}throw new Error("Not Implemented Error")})}clear(){return f(this,void 0,void 0,function*(){this.persistent&&this.db?yield this.db.clear("data"):this.data.clear()})}getCount(){return f(this,void 0,void 0,function*(){return this.persistent&&this.db?yield this.db.count("data"):this.data.size})}getAll(){return f(this,void 0,void 0,function*(){if(this.persistent&&this.db){const n=new Map,e=yield this.db.getAll("data");return e&&e.forEach(e=>{var t=e["_id"],e=he(e,["_id"]);n.set(t,e)}),n}return this.data})}toCsvData(){return f(this,void 0,void 0,function*(){const t=[];return t.push(this.headers),(yield this.getAll()).forEach(e=>{try{t.push(this.itemToRow(e))}catch(e){console.error(e)}}),t})}}const ye=["display: block;","padding: 0px 4px;","cursor: pointer;","text-align: center;"];function W(e){const t=document.createElement("div"),n=[...ye];return e&&n.push("flex-grow: 1;"),t.setAttribute("style",n.join("")),t}const ge=["margin-left: 4px;","margin-right: 4px;","border-left: 1px solid #2e2e2e;"];function X(){const e=document.createElement("div");return e.innerHTML=" ",e.setAttribute("style",ge.join("")),e}function g(e,t){var n,t=t||{};let r;const i=document.createElement("span");return(r=t.bold?(n=document.createElement("strong"),i.append(n),n):i).textContent=e,t.idAttribute&&r.setAttribute("id",t.idAttribute),i}const me=["position: fixed;","top: 0;","left: 0;","z-index: 10000;","width: 100%;","height: 100%;","pointer-events: none;"],be=["position: absolute;","bottom: 30px;","right: 30px;","width: auto;","pointer-events: auto;"],we=["align-items: center;","appearance: none;","background-color: #EEE;","border-radius: 4px;","border-width: 0;","box-shadow: rgba(45, 35, 66, 0.4) 0 2px 4px,rgba(45, 35, 66, 0.3) 0 7px 13px -3px,#D6D6E7 0 -3px 0 inset;","box-sizing: border-box;","color: #36395A;","display: flex;","font-family: monospace;","height: 38px;","justify-content: space-between;","line-height: 1;","list-style: none;","overflow: hidden;","padding-left: 16px;","padding-right: 16px;","position: relative;","text-align: left;","text-decoration: none;","user-select: none;","white-space: nowrap;","font-size: 18px;"];class ve{constructor(){this.ctas=[],this.canva=document.createElement("div"),this.canva.setAttribute("style",me.join("")),this.inner=document.createElement("div"),this.inner.setAttribute("style",be.join("")),this.canva.appendChild(this.inner),this.history=document.createElement("div"),this.inner.appendChild(this.history),this.container=document.createElement("div"),this.container.setAttribute("style",we.join("")),this.inner.appendChild(this.container)}makeItDraggable(){let t=0,n=0,r=0,i=0;const o=e=>{r=e.clientX-t,i=e.clientY-n,this.inner.style.right=window.innerWidth-r-this.inner.offsetWidth+"px",this.inner.style.bottom=window.innerHeight-i-this.inner.offsetHeight+"px"},e=(this.inner.addEventListener("mousedown",e=>{e.preventDefault(),t=e.clientX-this.inner.offsetLeft,n=e.clientY-this.inner.offsetTop,window.addEventListener("mousemove",o,!1)},!1),window.addEventListener("mouseup",()=>{window.removeEventListener("mousemove",o,!1)},!1),document.createElement("div"));e.style.cursor="move",e.innerHTML='',this.addCta(X()),this.addCta(e)}render(){document.body.appendChild(this.canva)}addCta(e,t){"u"<typeof t?this.ctas.push(e):this.ctas.splice(t,0,e),this.container.innerHTML="",this.ctas.forEach(e=>{this.container.appendChild(e)})}}!function(e){e.ADD="add",e.LOG="log"}(H=H||{});class xe extends pe{constructor(){super(...arguments),M(this,"name","fb-scrape-storage")}get headers(){return["Profile Id","Full Name","Profile Link","Bio","ImageSrc","GroupId","Group Joining Text","Profile Type"]}itemToRow(e){return[e.profileId,e.fullName,e.profileLink,e.bio,e.imageSrc,e.groupId,e.groupJoiningText,e.profileType]}}const m=new xe,J="fb-group-scraper-number-tracker",Ee="groupMemberExport";async function A(){const e=document.getElementById(J);if(e){const t=await m.getCount();e.textContent=t.toString()}}const y=new ve;function Ie(){const e=W(),t=(e.appendChild(g("Download ")),e.appendChild(g("0",{bold:!0,idAttribute:J})),e.appendChild(g(" users")),e.addEventListener("click",async function(){var e=(new Date).toISOString(),t=await m.toCsvData();try{ee(Ee+`-${e}.csv`,t)}catch(e){console.error("Error while generating export"),console.log(e.stack)}}),y.addCta(e),y.addCta(X()),W());t.appendChild(g("Reset")),t.addEventListener("click",async function(){await m.clear(),await A()}),y.addCta(t),y.makeItDraggable(),y.render(),window.setTimeout(()=>{A()},1e3)}function _e(e){var t;let n;if(null!=(t=null==e?void 0:e.data)&&t.group)n=e.data.group;else{if("Group"!==(null==(t=null==(t=null==e?void 0:e.data)?void 0:t.node)?void 0:t.__typename))return;n=e.data.node}let r;if(null!=(t=null==n?void 0:n.new_members)&&t.edges)r=n.new_members.edges;else if(null!=(e=null==n?void 0:n.new_forum_members)&&e.edges)r=n.new_forum_members.edges;else{if(null==(t=null==n?void 0:n.search_results)||!t.edges)return;r=n.search_results.edges}const i=r.map(e=>{var t="GroupUserInvite"===e.node.__isEntity?e.node.invitee_profile:e.node;if(!t)return null;var{id:n,name:r,bio_text:i,url:o,profile_picture:s,__isProfile:a}=t,d=(null==(d=null==e?void 0:e.join_status_text)?void 0:d.text)||(null==(e=null==(d=null==e?void 0:e.membership)?void 0:d.join_status_text)?void 0:e.text),t=null==(e=t.group_membership)?void 0:e.associated_group.id;return{profileId:n,fullName:r,profileLink:o,bio:(null==i?void 0:i.text)||"",imageSrc:(null==s?void 0:s.uri)||"",groupId:t,groupJoiningText:d||"",profileType:a}}),o=[];i.forEach(e=>{e&&o.push([e.profileId,e])}),m.addElems(o).then(()=>{A()})}function De(e){let n=[];try{n.push(JSON.parse(e))}catch(t){var r=e.split(` `);if(r.length<=1)return void console.error("Fail to parse API response",t);for(let e=0;e<r.length;e++){var i=r[e];try{n.push(JSON.parse(i))}catch{console.error("Fail to parse API response",t)}}}for(let e=0;e<n.length;e++)_e(n[e])}function Ce(){Ie();let e=XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open=function(){this.addEventListener("readystatechange",function(){this.responseURL.includes("/api/graphql/")&&4===this.readyState&&De(this.responseText)},!1),e.apply(this,arguments)}}Ce();
Open Chrome Developer Console
To open the Chrome Developer console on Chrome, use the keyboard shortcut Ctrl + Shift + I
(on Windows) or Cmd + Option + I
(on Mac).
Copy Paste the script
Select the "Console" tab and copy-paste the script from above. Facebook shows a warning message in the "Console" asking not to paste a script from a non-trustworthy source. It's true! And if you don't trust this script, stop here. Read the source code to understand what this script does.
Click on the "People" tab and scroll to load new members
In the Group Page, go to "People" and scroll to the bottom of the page. If the counter in the button text increases as your scroll, it's working!
Export members in CSV format
Once finished, or to perform "export checkpoints", click the button "Download X members". A Download window will prompt asking where to save your CSV file.
Edit and view your CSV file
To load and view the CSV file, use Datablist.com or any spreadsheet tools.
Manage your Facebook leads and enrich them with LinkedIn Profile
Use Facebook members profiles to build a leads database. Filter and segment leads to find the most relevant leads to contact. Then, enrich Facebook members with LinkedIn profile and email address. Follow this step-by-step tutorial to scrape Facebook members and find their LinkedIn profiles.
Find the email address for Facebook Group members
To be clear: there is no direct way to get the email address from Facebook. But we can use the name, the company name, or the LinkedIn Profile URL to find an email address! Read our guide to scrape Facebook Group Members and find their email address.
yarn install
yarn build
The generated script is located in dist/main.min.js
.