StKirill commited on
Commit
f13d9a9
·
verified ·
1 Parent(s): e7ade8f

Upload 2 files

Browse files
Files changed (2) hide show
  1. parsing.py +281 -0
  2. rachel_friends.csv +0 -0
parsing.py ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """parsing.ipynb
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1thvkAz498jADcaVirJG91V-3-XBhdkq1
8
+ """
9
+
10
+ import requests
11
+ from bs4 import BeautifulSoup
12
+
13
+ import re
14
+ import os
15
+
16
+ import pandas as pd
17
+ import numpy as np
18
+
19
+ from tqdm import tqdm
20
+
21
+ def get_transcripts_from_url(url):
22
+ # Send a GET request to the URL and retrieve the webpage content
23
+ response = requests.get(url)
24
+
25
+ # Parse the HTML content using Beautiful Soup
26
+ soup = BeautifulSoup(response.content, 'html.parser')
27
+
28
+ # Find elements by tag name
29
+ titles = soup.find_all('li')
30
+
31
+ # names for series
32
+ transcript_paths = []
33
+ # Extract text from elements
34
+ for title in titles:
35
+ a = title.find('a')
36
+
37
+ path = a.get("href")
38
+
39
+ transcript_paths.append("https://fangj.github.io/friends/" + path)
40
+
41
+ return transcript_paths
42
+
43
+ def get_text_from_html(url):
44
+ path = url
45
+ response = requests.get(path)
46
+ html_content = response.text
47
+
48
+ # Parse HTML content
49
+ soup = BeautifulSoup(html_content, 'html.parser')
50
+
51
+ transcript = soup.find_all('p')
52
+
53
+ transcript_name = path.split("/")[-1].replace(".html", ".txt")
54
+
55
+ with open(os.path.join("friends_raw_scripts", transcript_name), 'w', encoding='utf-8') as file:
56
+ text = soup.get_text(strip=False).lower().replace("'", ""). replace('"', "").replace("\xa0", "")
57
+ file.write(text + "\n")
58
+
59
+ return transcript_name
60
+
61
+ def clean_and_write_text(transcript_name):
62
+
63
+ char = []
64
+ texts = []
65
+ flag = None
66
+ pattern = re.compile(r'\b\w+:')
67
+
68
+ with open(os.path.join("friends_raw_scripts", transcript_name), 'r', encoding='utf-8') as file:
69
+ final_transcript = file.readlines()
70
+
71
+ skip_lines = 10
72
+ pattern = re.compile(r'\b\w+:')
73
+ scene_words = ["commercial break", "closing credits", "opening credits", "end"]
74
+ for ind in range(1, len(final_transcript) - 1):
75
+ final_list = []
76
+
77
+ pre_line = final_transcript[ind - 1].strip()
78
+ cur_line = final_transcript[ind].strip()
79
+ next_line = final_transcript[ind + 1].strip()
80
+
81
+ next_condition = re.sub(r"\([^()]*\)|\[[^\[\]]*\]", '', next_line).strip()
82
+ cur_conditon = re.sub(r"\([^()]*\)|\[[^\[\]]*\]", '', cur_line).strip()
83
+
84
+ if sum([bool(pre_line), bool(cur_line), bool(next_line)]) == 1:
85
+ continue
86
+
87
+ elif cur_line in scene_words:
88
+ continue
89
+
90
+ elif "by:" in cur_line or "note:" in cur_line:
91
+ continue
92
+
93
+ elif "[" in cur_line or "]" in cur_line:
94
+ continue
95
+
96
+ elif not cur_conditon:
97
+ continue
98
+
99
+ elif pattern.search(cur_line) and flag == None:
100
+ name, text = cur_line.split(":", maxsplit=1)
101
+ char.append(name)
102
+ text = re.sub(r'\([^)]*\)', '', text)
103
+ text = text.strip()
104
+ flag = "char"
105
+
106
+ if pattern.search(next_line) or not next_condition or next_line in scene_words or "[" in next_line:
107
+ texts.append(text)
108
+ flag = None
109
+
110
+ if len(char) != len(texts):
111
+ print(ind)
112
+ print(char[-1], texts[-1])
113
+
114
+ elif cur_line and flag == 'char':
115
+ text += " " + cur_line
116
+ if pattern.search(next_line) or not next_condition or next_line in scene_words or "[" in next_line:
117
+ text = re.sub(r"\([^()]*\)|\[[^\[\]]*\]", '', text).strip()
118
+ texts.append(text)
119
+ flag = None
120
+
121
+ if len(char) != len(texts):
122
+ print(ind)
123
+ print(char[-1], texts[-1])
124
+
125
+ new_name = "pre_" + transcript_name
126
+ with open(os.path.join("friends_preprocessed_scripts", new_name), 'w', encoding='utf-8') as file:
127
+ for c, d in zip(char, texts):
128
+ file.write(f"{c}: {d}\n")
129
+
130
+ raw_texts_exists = False # change on False to download transcripts and preprocess them
131
+ # parse data from website to get txt transcripts
132
+ transcript_paths = get_transcripts_from_url("https://fangj.github.io/friends/")
133
+
134
+ transcript_paths[:10]
135
+
136
+ os.makedirs("friends_preprocessed_scripts", exist_ok=True)
137
+ os.makedirs("friends_raw_scripts", exist_ok=True)
138
+
139
+ # define list with certain scripts from south park
140
+ # dir_list = [file for file in os.listdir("./raw_scripts")]
141
+ if not raw_texts_exists:
142
+ print("Parse all scripts from this website https://fangj.github.io/friends/")
143
+ for path in tqdm(transcript_paths, desc='Total'):
144
+ transcript_name = get_text_from_html(path)
145
+ clean_and_write_text(transcript_name)
146
+
147
+ dir_list = [file for file in os.listdir("./friends_preprocessed_scripts")]
148
+
149
+ def df_scripts(path):
150
+ """function take preprocessed_script.txt from dir and create dataframes"""
151
+ chars = []
152
+ texts = []
153
+
154
+ with open(os.path.join("friends_preprocessed_scripts", path), 'r', encoding="utf-8") as file:
155
+ for line in file:
156
+ char, text = line.split(":", 1)
157
+ chars.append(char)
158
+ texts.append(text.strip().lower())
159
+
160
+ df_name = path.replace("prep_SP_", "df_").replace(".txt", ".csv")
161
+ df = pd.DataFrame({'Characters': chars, 'Dialogs': texts})
162
+ df.to_csv(os.path.join("dataframes", "friends", df_name), index=False)
163
+
164
+ os.makedirs("dataframes/friends", exist_ok=True)
165
+
166
+ for preprocessed_script in dir_list:
167
+ df_scripts(preprocessed_script)
168
+
169
+ def collect_df(threshold=10):
170
+ """function concatenate dataframes in one single dataframe"""
171
+ dfs = []
172
+ for file in os.listdir("dataframes/friends"):
173
+ dfs.append(pd.read_csv(os.path.join("dataframes", "friends", file)))
174
+ df = pd.concat(dfs, ignore_index=True).dropna().reset_index(drop=True)
175
+ # find characters with more than 10 texts
176
+ high_chars = df.Characters.value_counts()
177
+ high_chars_ind = high_chars[high_chars > threshold].index
178
+ df = df[df["Characters"].isin(high_chars_ind)]
179
+ # optional function to clean dialogs
180
+ print(f"Number of characters in dataframe {len(df.Characters.value_counts())}")
181
+ return df
182
+
183
+ """### Which most frequent characters we can meet in the movie"""
184
+
185
+ def form_df(df, char):
186
+ # get indices where character is favorite_character
187
+ favorite_character_df = df[df.Characters == char] # .dropna()
188
+ favorite_character_ind = favorite_character_df.index.tolist()
189
+
190
+ # get indices where speech could be to favorite charecter
191
+ text_to_favorite_character_ind = (np.array(favorite_character_ind) - 1).tolist()
192
+
193
+ # form datasets with favorite charecter's dialogs and possible dialogs to favorite charecter
194
+ # favorite_character_dialog = df.iloc[favorite_character_ind] restore
195
+ favorite_character_dialog = df[df.index.isin(favorite_character_ind)]
196
+ # text_to_favorite_character = df.iloc[text_to_favorite_character_ind] restore# .dropna(subset=["Dialogs"])
197
+ text_to_favorite_character = df[df.index.isin(text_to_favorite_character_ind)]
198
+ # remove from text to cartman rows where speak Cartman
199
+ text_to_favorite_character = text_to_favorite_character[text_to_favorite_character["Characters"] != char]
200
+
201
+ # save data for debugging. Uncomment if necessary
202
+ # favorite_character_dialog.to_csv("test_favotite.csv", index=favorite_character_ind)
203
+ # text_to_favorite_character.to_csv("test_question.csv", index=text_to_favorite_character_ind)
204
+
205
+ # find in dialog_to_cartman lines with char "?"
206
+ # mask = text_to_favorite_character['Dialogs'].str.contains('\?')
207
+ # question_to_favorite_character = text_to_favorite_character[mask]
208
+ # if we want to get all texts to our favorite actor, then we leave text_to_favorite_character
209
+ question_to_favorite_character = text_to_favorite_character
210
+
211
+ # save data for debugging. Uncomment if necessary
212
+ # question_to_favorite_character.to_csv("question_to_favorite_character.csv")
213
+
214
+ question_to_favorite_character_ind = question_to_favorite_character.index.tolist()
215
+ true_answers_ind = (np.array(question_to_favorite_character_ind) + 1).tolist()
216
+ # favorite_character_answer = favorite_character_dialog.loc[true_answers_ind]
217
+ favorite_character_answer = favorite_character_dialog[favorite_character_dialog.index.isin(true_answers_ind)]
218
+ # save data for debugging. Uncomment if necessary
219
+ favorite_character_answer.to_csv("favorite_character_answer.csv")
220
+
221
+ # change name of columns for final dataframe
222
+ question_to_favorite_character = question_to_favorite_character.rename(
223
+ columns={"Characters": "questioner", "Dialogs": "question"})
224
+ favorite_character_answer = favorite_character_answer.rename(columns={"Characters": "answerer", "Dialogs": "answer"}) # char or answerer !!!!!!
225
+
226
+ question_to_favorite_character.reset_index(inplace=True, drop=True)
227
+ favorite_character_answer.reset_index(inplace=True, drop=True)
228
+
229
+ df = pd.concat([question_to_favorite_character, favorite_character_answer], axis=1)
230
+
231
+ return df
232
+
233
+ def form_df_negative(df, df_char, char):
234
+ # get from form_df true data, but without labels. At this step define label = 1 for all sentences
235
+ true_label = pd.DataFrame({"label": np.ones(shape=len(df_char), dtype=np.int8)})
236
+ # add from the right side new columns with labels
237
+ df_true_labels = pd.concat([df_char, true_label], axis=1)
238
+
239
+
240
+ # find text for this random_character and without questions
241
+ # favorite_character_df = df[df.Characters == random_char].str.contains('\?')
242
+ random_character_df = df[df.Characters != char].reset_index(drop=True)
243
+
244
+ indices = np.random.choice(np.arange(len(random_character_df)), size=(len(df_true_labels)), replace=False)
245
+ random_character_df = random_character_df[random_character_df.index.isin(indices)]
246
+ df_negative_labels = df_true_labels.drop(columns="label", axis=1)
247
+ df_negative_labels["answer"] = random_character_df["Dialogs"].reset_index(drop=True)
248
+ df_negative_labels = df_negative_labels.rename(columns={"Dialogs": "question"})
249
+
250
+ negative_label = pd.DataFrame({"label": np.zeros(shape=len(df_char), dtype=np.int8)})
251
+ df_negative_labels = pd.concat([df_negative_labels, negative_label], axis=1)
252
+
253
+ # fincal concatenation of dataframes with true and negative labels
254
+ final_df = pd.concat([df_negative_labels, df_true_labels], axis=0)
255
+
256
+
257
+ # How to shuffle data in pandas dataframe
258
+ final_df = final_df.sample(frac=1).reset_index(drop=True)
259
+
260
+ return final_df
261
+
262
+ """## Choose your favorite character"""
263
+
264
+ # concatenate data in one single dataframe
265
+ df = collect_df(threshold=10)
266
+ df.to_csv("full_trancscripts.csv", index=False)
267
+
268
+ # form the final dataset for tf-idf / word2vec, which no need labels between strings
269
+ characters = ["rachel", "ross", "chandler", "monica", "joey", "phoebe"]
270
+
271
+ for char in tqdm(characters):
272
+ df_char = form_df(df, char)
273
+ # create final dataframe
274
+ df_char.to_csv(char + "_friends.csv", index=False)
275
+
276
+ df_char_label = form_df_negative(df, df_char, char)
277
+ df_char_label.to_csv(char + "_friends_label.csv", index=False)
278
+
279
+ print("script created")
280
+
281
+
rachel_friends.csv ADDED
The diff for this file is too large to render. See raw diff