|  |  | 
					
						
						|  | """parsing.ipynb | 
					
						
						|  |  | 
					
						
						|  | Automatically generated by Colaboratory. | 
					
						
						|  |  | 
					
						
						|  | Original file is located at | 
					
						
						|  | https://colab.research.google.com/drive/1thvkAz498jADcaVirJG91V-3-XBhdkq1 | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | import requests | 
					
						
						|  | from bs4 import BeautifulSoup | 
					
						
						|  |  | 
					
						
						|  | import re | 
					
						
						|  | import os | 
					
						
						|  |  | 
					
						
						|  | import pandas as pd | 
					
						
						|  | import numpy as np | 
					
						
						|  |  | 
					
						
						|  | from tqdm import tqdm | 
					
						
						|  |  | 
					
						
						|  | def get_transcripts_from_url(url): | 
					
						
						|  |  | 
					
						
						|  | response = requests.get(url) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | soup = BeautifulSoup(response.content, 'html.parser') | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | titles = soup.find_all('li') | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | transcript_paths = [] | 
					
						
						|  |  | 
					
						
						|  | for title in titles: | 
					
						
						|  | a = title.find('a') | 
					
						
						|  |  | 
					
						
						|  | path = a.get("href") | 
					
						
						|  |  | 
					
						
						|  | transcript_paths.append("https://fangj.github.io/friends/" + path) | 
					
						
						|  |  | 
					
						
						|  | return transcript_paths | 
					
						
						|  |  | 
					
						
						|  | def get_text_from_html(url): | 
					
						
						|  | path = url | 
					
						
						|  | response = requests.get(path) | 
					
						
						|  | html_content = response.text | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | soup = BeautifulSoup(html_content, 'html.parser') | 
					
						
						|  |  | 
					
						
						|  | transcript = soup.find_all('p') | 
					
						
						|  |  | 
					
						
						|  | transcript_name = path.split("/")[-1].replace(".html", ".txt") | 
					
						
						|  |  | 
					
						
						|  | with open(os.path.join("friends_raw_scripts", transcript_name), 'w', encoding='utf-8') as file: | 
					
						
						|  | text = soup.get_text(strip=False).lower().replace("'", ""). replace('"', "").replace("\xa0", "") | 
					
						
						|  | file.write(text + "\n") | 
					
						
						|  |  | 
					
						
						|  | return transcript_name | 
					
						
						|  |  | 
					
						
						|  | def clean_and_write_text(transcript_name): | 
					
						
						|  |  | 
					
						
						|  | char = [] | 
					
						
						|  | texts = [] | 
					
						
						|  | flag = None | 
					
						
						|  | pattern = re.compile(r'\b\w+:') | 
					
						
						|  |  | 
					
						
						|  | with open(os.path.join("friends_raw_scripts", transcript_name), 'r', encoding='utf-8') as file: | 
					
						
						|  | final_transcript = file.readlines() | 
					
						
						|  |  | 
					
						
						|  | skip_lines = 10 | 
					
						
						|  | pattern = re.compile(r'\b\w+:') | 
					
						
						|  | scene_words = ["commercial break", "closing credits", "opening credits", "end"] | 
					
						
						|  | for ind in range(1, len(final_transcript) - 1): | 
					
						
						|  | final_list = [] | 
					
						
						|  |  | 
					
						
						|  | pre_line = final_transcript[ind - 1].strip() | 
					
						
						|  | cur_line = final_transcript[ind].strip() | 
					
						
						|  | next_line = final_transcript[ind + 1].strip() | 
					
						
						|  |  | 
					
						
						|  | next_condition = re.sub(r"\([^()]*\)|\[[^\[\]]*\]", '', next_line).strip() | 
					
						
						|  | cur_conditon = re.sub(r"\([^()]*\)|\[[^\[\]]*\]", '', cur_line).strip() | 
					
						
						|  |  | 
					
						
						|  | if sum([bool(pre_line), bool(cur_line), bool(next_line)]) == 1: | 
					
						
						|  | continue | 
					
						
						|  |  | 
					
						
						|  | elif cur_line in scene_words: | 
					
						
						|  | continue | 
					
						
						|  |  | 
					
						
						|  | elif "by:" in cur_line or "note:" in cur_line: | 
					
						
						|  | continue | 
					
						
						|  |  | 
					
						
						|  | elif "[" in cur_line or "]" in cur_line: | 
					
						
						|  | continue | 
					
						
						|  |  | 
					
						
						|  | elif not cur_conditon: | 
					
						
						|  | continue | 
					
						
						|  |  | 
					
						
						|  | elif pattern.search(cur_line) and flag == None: | 
					
						
						|  | name, text = cur_line.split(":", maxsplit=1) | 
					
						
						|  | char.append(name) | 
					
						
						|  | text = re.sub(r'\([^)]*\)', '', text) | 
					
						
						|  | text = text.strip() | 
					
						
						|  | flag = "char" | 
					
						
						|  |  | 
					
						
						|  | if pattern.search(next_line) or not next_condition or next_line in scene_words or "[" in next_line: | 
					
						
						|  | texts.append(text) | 
					
						
						|  | flag = None | 
					
						
						|  |  | 
					
						
						|  | if len(char) != len(texts): | 
					
						
						|  | print(ind) | 
					
						
						|  | print(char[-1], texts[-1]) | 
					
						
						|  |  | 
					
						
						|  | elif cur_line and flag == 'char': | 
					
						
						|  | text += " " + cur_line | 
					
						
						|  | if pattern.search(next_line) or not next_condition or next_line in scene_words or "[" in next_line: | 
					
						
						|  | text = re.sub(r"\([^()]*\)|\[[^\[\]]*\]", '', text).strip() | 
					
						
						|  | texts.append(text) | 
					
						
						|  | flag = None | 
					
						
						|  |  | 
					
						
						|  | if len(char) != len(texts): | 
					
						
						|  | print(ind) | 
					
						
						|  | print(char[-1], texts[-1]) | 
					
						
						|  |  | 
					
						
						|  | new_name = "pre_" + transcript_name | 
					
						
						|  | with open(os.path.join("friends_preprocessed_scripts", new_name), 'w', encoding='utf-8') as file: | 
					
						
						|  | for c, d in zip(char, texts): | 
					
						
						|  | file.write(f"{c}: {d}\n") | 
					
						
						|  |  | 
					
						
						|  | raw_texts_exists = False | 
					
						
						|  |  | 
					
						
						|  | transcript_paths = get_transcripts_from_url("https://fangj.github.io/friends/") | 
					
						
						|  |  | 
					
						
						|  | transcript_paths[:10] | 
					
						
						|  |  | 
					
						
						|  | os.makedirs("friends_preprocessed_scripts", exist_ok=True) | 
					
						
						|  | os.makedirs("friends_raw_scripts", exist_ok=True) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if not raw_texts_exists: | 
					
						
						|  | print("Parse all scripts from this website https://fangj.github.io/friends/") | 
					
						
						|  | for path in tqdm(transcript_paths, desc='Total'): | 
					
						
						|  | transcript_name = get_text_from_html(path) | 
					
						
						|  | clean_and_write_text(transcript_name) | 
					
						
						|  |  | 
					
						
						|  | dir_list = [file for file in os.listdir("./friends_preprocessed_scripts")] | 
					
						
						|  |  | 
					
						
						|  | def df_scripts(path): | 
					
						
						|  | """function take preprocessed_script.txt from dir and create dataframes""" | 
					
						
						|  | chars = [] | 
					
						
						|  | texts = [] | 
					
						
						|  |  | 
					
						
						|  | with open(os.path.join("friends_preprocessed_scripts", path), 'r', encoding="utf-8") as file: | 
					
						
						|  | for line in file: | 
					
						
						|  | char, text = line.split(":", 1) | 
					
						
						|  | chars.append(char) | 
					
						
						|  | texts.append(text.strip().lower()) | 
					
						
						|  |  | 
					
						
						|  | df_name = path.replace("prep_SP_", "df_").replace(".txt", ".csv") | 
					
						
						|  | df = pd.DataFrame({'Characters': chars, 'Dialogs': texts}) | 
					
						
						|  | df.to_csv(os.path.join("dataframes", "friends", df_name), index=False) | 
					
						
						|  |  | 
					
						
						|  | os.makedirs("dataframes/friends", exist_ok=True) | 
					
						
						|  |  | 
					
						
						|  | for preprocessed_script in dir_list: | 
					
						
						|  | df_scripts(preprocessed_script) | 
					
						
						|  |  | 
					
						
						|  | def collect_df(threshold=10): | 
					
						
						|  | """function concatenate dataframes in one single dataframe""" | 
					
						
						|  | dfs = [] | 
					
						
						|  | for file in os.listdir("dataframes/friends"): | 
					
						
						|  | dfs.append(pd.read_csv(os.path.join("dataframes", "friends", file))) | 
					
						
						|  | df = pd.concat(dfs, ignore_index=True).dropna().reset_index(drop=True) | 
					
						
						|  |  | 
					
						
						|  | high_chars = df.Characters.value_counts() | 
					
						
						|  | high_chars_ind = high_chars[high_chars > threshold].index | 
					
						
						|  | df = df[df["Characters"].isin(high_chars_ind)] | 
					
						
						|  |  | 
					
						
						|  | print(f"Number of characters in dataframe {len(df.Characters.value_counts())}") | 
					
						
						|  | return df | 
					
						
						|  |  | 
					
						
						|  | """### Which most frequent characters we can meet in the movie""" | 
					
						
						|  |  | 
					
						
						|  | def form_df(df, char): | 
					
						
						|  |  | 
					
						
						|  | favorite_character_df = df[df.Characters == char] | 
					
						
						|  | favorite_character_ind = favorite_character_df.index.tolist() | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | text_to_favorite_character_ind = (np.array(favorite_character_ind) - 1).tolist() | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | favorite_character_dialog = df[df.index.isin(favorite_character_ind)] | 
					
						
						|  |  | 
					
						
						|  | text_to_favorite_character = df[df.index.isin(text_to_favorite_character_ind)] | 
					
						
						|  |  | 
					
						
						|  | text_to_favorite_character = text_to_favorite_character[text_to_favorite_character["Characters"] != char] | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | question_to_favorite_character = text_to_favorite_character | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | question_to_favorite_character_ind = question_to_favorite_character.index.tolist() | 
					
						
						|  | true_answers_ind = (np.array(question_to_favorite_character_ind) + 1).tolist() | 
					
						
						|  |  | 
					
						
						|  | favorite_character_answer = favorite_character_dialog[favorite_character_dialog.index.isin(true_answers_ind)] | 
					
						
						|  |  | 
					
						
						|  | favorite_character_answer.to_csv("favorite_character_answer.csv") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | question_to_favorite_character = question_to_favorite_character.rename( | 
					
						
						|  | columns={"Characters": "questioner", "Dialogs": "question"}) | 
					
						
						|  | favorite_character_answer = favorite_character_answer.rename(columns={"Characters": "answerer", "Dialogs": "answer"}) | 
					
						
						|  |  | 
					
						
						|  | question_to_favorite_character.reset_index(inplace=True, drop=True) | 
					
						
						|  | favorite_character_answer.reset_index(inplace=True, drop=True) | 
					
						
						|  |  | 
					
						
						|  | df = pd.concat([question_to_favorite_character, favorite_character_answer], axis=1) | 
					
						
						|  |  | 
					
						
						|  | return df | 
					
						
						|  |  | 
					
						
						|  | def form_df_negative(df, df_char, char): | 
					
						
						|  |  | 
					
						
						|  | true_label = pd.DataFrame({"label": np.ones(shape=len(df_char), dtype=np.int8)}) | 
					
						
						|  |  | 
					
						
						|  | df_true_labels = pd.concat([df_char, true_label], axis=1) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | random_character_df = df[df.Characters != char].reset_index(drop=True) | 
					
						
						|  |  | 
					
						
						|  | indices = np.random.choice(np.arange(len(random_character_df)), size=(len(df_true_labels)), replace=False) | 
					
						
						|  | random_character_df = random_character_df[random_character_df.index.isin(indices)] | 
					
						
						|  | df_negative_labels = df_true_labels.drop(columns="label", axis=1) | 
					
						
						|  | df_negative_labels["answer"] = random_character_df["Dialogs"].reset_index(drop=True) | 
					
						
						|  | df_negative_labels = df_negative_labels.rename(columns={"Dialogs": "question"}) | 
					
						
						|  |  | 
					
						
						|  | negative_label = pd.DataFrame({"label": np.zeros(shape=len(df_char), dtype=np.int8)}) | 
					
						
						|  | df_negative_labels = pd.concat([df_negative_labels, negative_label], axis=1) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | final_df = pd.concat([df_negative_labels, df_true_labels], axis=0) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | final_df = final_df.sample(frac=1).reset_index(drop=True) | 
					
						
						|  |  | 
					
						
						|  | return final_df | 
					
						
						|  |  | 
					
						
						|  | """## Choose your favorite character""" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | df = collect_df(threshold=10) | 
					
						
						|  | df.to_csv("full_trancscripts.csv", index=False) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | characters = ["rachel", "ross", "chandler", "monica", "joey", "phoebe"] | 
					
						
						|  |  | 
					
						
						|  | for char in tqdm(characters): | 
					
						
						|  | df_char = form_df(df, char) | 
					
						
						|  |  | 
					
						
						|  | df_char.to_csv(char + "_friends.csv", index=False) | 
					
						
						|  |  | 
					
						
						|  | df_char_label = form_df_negative(df, df_char, char) | 
					
						
						|  | df_char_label.to_csv(char + "_friends_label.csv", index=False) | 
					
						
						|  |  | 
					
						
						|  | print("script created") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  |