| | |
| | """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") |
| |
|
| |
|
| |
|