Как извлечь текст из нескольких веб-страниц, на некоторых из которых есть текст под разными тегами? - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь извлечь все стенограммы из этого URL - https://fangj.github.io/friends/

Я пробовал свой код, но

  • эпизод 217-223 не получаетизвлечено полностью.

  • эпизод 302. ни один из транскриптов не извлечен.

  • эпизод 224, 921, 1015 (и многие другие) не имеютпо одной строке на диалог.

  • и т. д.

Если я правильно понимаю, многие веб-страницы имеют различную структуру текста, котораязатрудняет обобщение кода, если я не пропускаю что-то здесь.

Моя цель - получить текст как есть с веб-страниц в текстовые файлы симя эпизода в качестве имени файла - то есть 0101.txt, 0310.txt и т. д., как расширение конца URL.Прямо сейчас я собрал их все вручную ctrl+a + ctrl+c + ctrl+v.Я хочу очистить его, чтобы я мог автоматизировать этот процесс.Прямо сейчас эта альтернатива должна использовать pyautogui для этого.Но я предпочитаю очистку веб-страниц, если это возможно.Я открыт для других библиотек в Python, если они существуют.

CODE

import requests
from bs4 import BeautifulSoup

url = "https://fangj.github.io/friends/"

page_content = requests.get(url, timeout=5)

page_html = BeautifulSoup(page_content.content, "html.parser")

list_of_links = page_html.findAll('a')

list_of_hrefs = []
for href in list_of_links:
    if href.has_attr('href'):
        list_of_hrefs.append(href.attrs['href'])

episode_nos = []
for link in list_of_hrefs:
    episode_nos.append(link.split('/')[1].split('.')[0])

list_of_urls = []
for href in list_of_hrefs:
    list_of_urls.append(url+href)

for episode_no, one_url in enumerate(list_of_urls):
    episode_content = requests.get(one_url, timeout=5)
    episode_html = BeautifulSoup(episode_content.content, "html.parser")

    episode_dialogues = episode_html.findAll('p')

    with open('../../data/raw/{}.txt'.format(episode_nos[episode_no]), 'w', encoding='utf-8') as file:
        for text in episode_dialogues:
            file.write(text.text.replace('\n', ' ') + '\n')

1 Ответ

0 голосов
/ 28 ноября 2018

Вы можете выбрать весь текст HTML-тега, чтобы получить все внутри каждой ссылки эпизода, т.е. select_one('html').text.Это кажется намного проще.

Вы можете использовать селектор атрибута css = значение с оператором ^ (чтобы указать, что значение атрибута начинается с подстроки справа от =), чтобы собрать все начальные ссылки эпизода, т.е.[href^='season'].

Поскольку вы делаете много звонков, вы можете повторно использовать соединение с сеансом.Я полагаю, что многопроцессорность может быть хорошей идеей и здесь.

import requests
import pandas as pd
from bs4 import BeautifulSoup
import ftfy

session = requests.Session()

def makeSoup(url):
    res = session.get(url,timeout=5)
    res.raise_for_status()
    soup_content = BeautifulSoup(res.content, "lxml")
    for style in soup_content(["style"]):
        style.decompose()
    return soup_content

url = "https://fangj.github.io/friends/"
soup = makeSoup(url)

links = [url + link['href'] for link in soup.select("[href^='season']")]
results = [[link.split('season/')[1].split('.html')[0], makeSoup(link).select_one('html').text] for link in links]

df = pd.DataFrame(results)

for index, row in df.iterrows():
    with open('data/' + row[0] + '.txt', 'w', encoding='utf-8') as file:
        file.write(ftfy.fix_text(row[1]))

Вы можете сделать то, что вам нужно, с полученным текстом.

...