Facebook 데이터와 JavaScript로 쓸모없는 친구를 버리다
23968 단어 webdevjavascript
나는 어떤 친구를 버릴지 결정해야 한다.근데 기준이 뭐예요?보다지력돈.
물론 개인의 가치는 주관적이다.경험을 기준으로 할 방법이 없지, 그렇지?틀렸어.친구의 가치를 평가하는 믿을 만한 방법은 페이스북 메신저에서 받은 표정 반응량이다.
더 많은 웃음소리는 이것이 바로 재미있는 친구라는 것을 의미한다.가장 분노한 반응은 논쟁적인 반응이다.등등이해하기 쉽다
인공 계수는 불가능하다.나는 자동으로 이 임무를 완성해야 한다.
데이터 가져오기
채팅 삭제가 너무 느려요.API가 하나 있지만 여기에 해당하는지 모르겠습니다.그것은 보기에 매우 무섭다. 문서에 글이 너무 많다.나는 마침내 필요한 데이터를 얻는 방법을 찾았다.
Facebook lets me download all the deeply personal information여 년 동안 그들은 읽기 쉬운 JSON 형식으로 나의 정보를 수집했다.그들은 매우 좋다!필요한 데이터(메시지)만 선택하고 최소한의 이미지 품질을 선택하여 아카이브를 최소화합니다.그것은 생성되기까지 몇 시간, 심지어 며칠이 걸릴 수도 있다.
다음 날, 나는 아카이브가 사용 가능한 복사본 탭에서 다운로드할 준비가 되어 있다는 이메일을 받았다.zip 파일에는 다음과 같은 구조가 있습니다.
messages
├── archived_threads
│ └── [chats]
├── filtered_threads
│ └── [chats]
├── inbox
│ └── [chats]
├── message_requests
│ └── [chats]
└── stickers_used
└── [bunch of PNGs]
내가 관심 있는 목록은 inbox
이다.[chats]
디렉토리에는 다음과 같은 구조가 있습니다.
[ChatTitle]_[uniqueid]
├── gifs
│ └── [shared gifs]
├── photos
│ └── [shared photos]
├── videos
│ └── [shared videos]
├── files
│ └── [other shared files]
└── message_1.json
내가 필요로 하는 데이터는 message_1.json
이다._1
접미사가 왜 필요한지 모르겠어요.내 파일에는 message_2.json
또는 그 어떠한 변체도 없다.
예를 들어 내가 사용하고 싶은 채팅 이름이'나체 배구 파트너'라면 전체 경로는 messages/inbox/NudeVolleyballBuddies_5tujptrnrm/message_1.json
과 유사할 것이다.
이 파일들은 상당히 커질 수 있습니다. 따라서 좋아하는 IDE가 그것을 보자마자 쓰러지면 놀라지 마십시오.내가 분석하고 싶은 채팅은 약 5년 동안 백만 줄이 넘는 JSON이 생겼다.
JSON 파일의 구조는 다음과 같습니다.
{
"participants": [
{ "name": "Ricardo L" },
{ "name": "etc..." }
],
"messages": [
" (list of messages...) "
],
"title": "Nude Volleyball Buddies",
"is_still_participant": true,
"thread_type": "RegularGroup",
"thread_path": "inbox/NudeVolleyballBuddies_5tujptrnrm"
}
messages
에 주목하고 싶습니다.각 메시지에는 다음 형식이 있습니다.
{
"sender_name": "Ricardo L",
"timestamp_ms": 1565448249085,
"content": "is it ok if i wear a sock",
"reactions": [
{
"reaction": "\u00f0\u009f\u0098\u00a2",
"actor": "Samuel L"
},
{
"reaction": "\u00f0\u009f\u0098\u00a2",
"actor": "Carmen Franco"
}
],
"type": "Generic"
}
내가 원하는 걸 찾았어!여기에 모든 반응이 열거되어 있다.
JavaScript에서 JSON 읽기
이 작업에 FileReader API을 사용합니다.
<input type="file" accept=".json" onChange="handleChange(this)">
function handleChange(target) {
const reader = new FileReader();
reader.onload = handleReaderLoad;
reader.readAsText(target.files[0]);
}
function handleReaderLoad (event) {
const parsedObject = JSON.parse(event.target.result);
console.log('parsed object', parsedObject);
}
페이지에서 파일 입력 필드를 보았습니다. JSON을 선택할 때 해결된 JavaScript 객체가 콘솔에 기록됩니다.길이가 너무 길어서 몇 초가 걸릴지도 몰라요.지금 나는 그것을 어떻게 읽는지 확실히 알아야 한다.
분석 데이터
간단하게 시작합시다.나의 첫 번째 목표는 나의 messages_1.json
을 입력으로 하는 것이다. 이와 같은 내용을 출력으로 하는 것이다.
output = [
{
name: 'Ricardo L',
counts: {
'😂': 10,
'😍': 3,
'😢': 4,
},
},
{
name: 'Samuel L',
counts: {
'😂': 4,
'😍': 5,
'😢': 12,
},
},
// etc for every participant
]
원본 JSON의 participants
객체는 이미 유사한 형식을 가지고 있습니다.counts
필드만 추가하면 됩니다.
const output = parsedObject.participants.map(({ name }) => ({
name,
counts: {},
}))
이제 전체 메시지 목록을 교체하고 반응 계수를 누적해야 합니다.
parsedObject.messages.forEach(message => {
// Find the correct participant in the output object
const outputParticipant = output.find(({ name }) => name === message.sender_name)
// Increment the reaction counts for that participant
message.reactions.forEach(({ reaction }) => {
if (!outputParticipant.counts[reaction]) {
outputParticipant.counts[reaction] = 1
} else {
outputParticipant.counts[reaction] += 1
}
})
})
기록된 출력은 다음과 같습니다.
나는 이모티콘이 아니라 네 개의 이상한 기호를 얻었다.무슨 좋은 점이 있습니까?
반응 이모티콘 디코딩
나는 메시지를 예로 들었다. 그것은 단지 하나의 반응뿐이었다. 우는 이모티콘(😢). JSON 파일을 검토한 결과
"reaction": "\u00f0\u009f\u0098\u00a2"
이 캐릭터 훈련과 울음 이모티콘은 어떤 관계가 있습니까?
보기에는 그렇지 않을 수도 있지만, 이 문자열은 네 글자 길이가 있다.
messages
├── archived_threads
│ └── [chats]
├── filtered_threads
│ └── [chats]
├── inbox
│ └── [chats]
├── message_requests
│ └── [chats]
└── stickers_used
└── [bunch of PNGs]
[ChatTitle]_[uniqueid]
├── gifs
│ └── [shared gifs]
├── photos
│ └── [shared photos]
├── videos
│ └── [shared videos]
├── files
│ └── [other shared files]
└── message_1.json
{
"participants": [
{ "name": "Ricardo L" },
{ "name": "etc..." }
],
"messages": [
" (list of messages...) "
],
"title": "Nude Volleyball Buddies",
"is_still_participant": true,
"thread_type": "RegularGroup",
"thread_path": "inbox/NudeVolleyballBuddies_5tujptrnrm"
}
{
"sender_name": "Ricardo L",
"timestamp_ms": 1565448249085,
"content": "is it ok if i wear a sock",
"reactions": [
{
"reaction": "\u00f0\u009f\u0098\u00a2",
"actor": "Samuel L"
},
{
"reaction": "\u00f0\u009f\u0098\u00a2",
"actor": "Carmen Franco"
}
],
"type": "Generic"
}
이 작업에 FileReader API을 사용합니다.
<input type="file" accept=".json" onChange="handleChange(this)">
function handleChange(target) {
const reader = new FileReader();
reader.onload = handleReaderLoad;
reader.readAsText(target.files[0]);
}
function handleReaderLoad (event) {
const parsedObject = JSON.parse(event.target.result);
console.log('parsed object', parsedObject);
}
페이지에서 파일 입력 필드를 보았습니다. JSON을 선택할 때 해결된 JavaScript 객체가 콘솔에 기록됩니다.길이가 너무 길어서 몇 초가 걸릴지도 몰라요.지금 나는 그것을 어떻게 읽는지 확실히 알아야 한다.분석 데이터
간단하게 시작합시다.나의 첫 번째 목표는 나의 messages_1.json
을 입력으로 하는 것이다. 이와 같은 내용을 출력으로 하는 것이다.
output = [
{
name: 'Ricardo L',
counts: {
'😂': 10,
'😍': 3,
'😢': 4,
},
},
{
name: 'Samuel L',
counts: {
'😂': 4,
'😍': 5,
'😢': 12,
},
},
// etc for every participant
]
원본 JSON의 participants
객체는 이미 유사한 형식을 가지고 있습니다.counts
필드만 추가하면 됩니다.
const output = parsedObject.participants.map(({ name }) => ({
name,
counts: {},
}))
이제 전체 메시지 목록을 교체하고 반응 계수를 누적해야 합니다.
parsedObject.messages.forEach(message => {
// Find the correct participant in the output object
const outputParticipant = output.find(({ name }) => name === message.sender_name)
// Increment the reaction counts for that participant
message.reactions.forEach(({ reaction }) => {
if (!outputParticipant.counts[reaction]) {
outputParticipant.counts[reaction] = 1
} else {
outputParticipant.counts[reaction] += 1
}
})
})
기록된 출력은 다음과 같습니다.
나는 이모티콘이 아니라 네 개의 이상한 기호를 얻었다.무슨 좋은 점이 있습니까?
반응 이모티콘 디코딩
나는 메시지를 예로 들었다. 그것은 단지 하나의 반응뿐이었다. 우는 이모티콘(😢). JSON 파일을 검토한 결과
"reaction": "\u00f0\u009f\u0098\u00a2"
이 캐릭터 훈련과 울음 이모티콘은 어떤 관계가 있습니까?
보기에는 그렇지 않을 수도 있지만, 이 문자열은 네 글자 길이가 있다.
output = [
{
name: 'Ricardo L',
counts: {
'😂': 10,
'😍': 3,
'😢': 4,
},
},
{
name: 'Samuel L',
counts: {
'😂': 4,
'😍': 5,
'😢': 12,
},
},
// etc for every participant
]
const output = parsedObject.participants.map(({ name }) => ({
name,
counts: {},
}))
parsedObject.messages.forEach(message => {
// Find the correct participant in the output object
const outputParticipant = output.find(({ name }) => name === message.sender_name)
// Increment the reaction counts for that participant
message.reactions.forEach(({ reaction }) => {
if (!outputParticipant.counts[reaction]) {
outputParticipant.counts[reaction] = 1
} else {
outputParticipant.counts[reaction] += 1
}
})
})
나는 메시지를 예로 들었다. 그것은 단지 하나의 반응뿐이었다. 우는 이모티콘(😢). JSON 파일을 검토한 결과
"reaction": "\u00f0\u009f\u0098\u00a2"
이 캐릭터 훈련과 울음 이모티콘은 어떤 관계가 있습니까?보기에는 그렇지 않을 수도 있지만, 이 문자열은 네 글자 길이가 있다.
\u00f0
\u009f
\u0098
\u00a2
\u
은 이스케이프 시퀀스를 나타내는 접두사입니다.이 특수한 전의 서열은 \u
에서 시작하여 뒤에 네 개의 16진 숫자와 같다.UTF-16 형식의 유니코드 문자를 나타냅니다.주의: it's a bit more complicated than that, 그러나 본고에서 우리는 모든 내용을 UTF-16로 간주할 수 있다.예를 들어, the Unicode hex code of the capital letter S is
0053
.콘솔에 "\u0053"
을 입력하여 JavaScript에서 작동하는 방식을 볼 수 있습니다.유니코드 테이블을 다시 한 번 보니 the hex code for the crying emoji is
1F622
이 보입니다.이는 네 자리수보다 길기 때문에 \u1F622
을 간단하게 사용하면 안 된다.두 가지 해결 방법이 있습니다.\ud83d\ude22
을 나타낸다.\u{1F622}
.코드를 괄호로 묶는 것을 주의하십시오.그럼 얘네는 뭐야?
우리 한 조 possible encodings for this emoji을 봅시다.이게 익숙해 보여요?
너무 가까워!이것은 16진수 형식의 UTF-8 인코딩이라는 사실이 증명되었다.그러나 어떤 이유로 모든 바이트는 UTF-16 형식으로 유니코드 문자를 쓴다.
이 점을 알고 있습니다.
\u00f0\u009f\u0098\u00a2
에서 \uD83D\uDE22
까지 어떻게 합니까?각 문자를 바이트로 추출한 다음 바이트를 UTF-8 문자열로 결합합니다.
function decodeFBEmoji (fbString) {
// Convert String to Array of hex codes
const codeArray = (
fbString // starts as '\u00f0\u009f\u0098\u00a2'
.split('')
.map(char => (
char.charCodeAt(0) // convert '\u00f0' to 0xf0
)
); // result is [0xf0, 0x9f, 0x98, 0xa2]
// Convert plain JavaScript array to Uint8Array
const byteArray = Uint8Array.from(codeArray);
// Decode byte array as a UTF-8 string
return new TextDecoder('utf-8').decode(byteArray); // '😢'
}
이제 정확한 렌더링 결과에 필요한 것이 생겼습니다.버릴 친구를 고르다
나는 매 반응의 횟수에 따라 점수를 계산하고 싶다.변수가 필요합니다.
결과는 점수가 높을수록 사람이 좋다.Here is an explanation of how I reached this equation.
JavaScript에서는 다음과 같습니다.
participants.forEach((participant) => {
const {
reactions,
sentReactionCount,
messageCount,
} = participant
const approval = reactions['👍']
const disapproval = reactions['👎']
const positiveEmotion = reactions['😆'] + reactions['😍']
const negativeEmotions = reactions['😢'] + reactions['😠']
const positiveFactor = (2 * approval + 3 * positiveEmotion + sentReactionCount)
const negativeFactor = (2 * disapproval + 3 * negativeEmotions)
const totalMessageFactor = Math.abs(messageCount - messageCountAverage) / (messageCountAverage)
participant.score = (positiveFactor - negativeFactor) / totalMessageFactor
})
정보를 테이블로 표시하여 보다 쉽게 확인할 수 있습니다.주: 프라이버시를 고려하여 나는 친구의 실제 이름을 그들의 가정 주소로 바꾸었다.
안녕히 가세요.
표를 빠르게 훑어보면, 나는 마침내 내가 내 생활에서 누구를 삭제해야 할지 결정할 수 있다.
안녕히 계세요, 샘 사촌 형.
Reference
이 문제에 관하여(Facebook 데이터와 JavaScript로 쓸모없는 친구를 버리다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/raicuparta/ditching-worthless-friends-with-facebook-data-and-javascript-3f2i
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Facebook 데이터와 JavaScript로 쓸모없는 친구를 버리다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/raicuparta/ditching-worthless-friends-with-facebook-data-and-javascript-3f2i텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)