python - 如何从多个网页中提取文本,其中某些页面在不同标签下有文本?

标签 python web-scraping beautifulsoup python-requests

我正在尝试从此网址提取所有文字记录 - https://fangj.github.io/friends/

我已经尝试过我的代码,但是

  • 第 217-223 集未完全提取。

  • 第 302 集没有提取任何文字记录。

  • 第 224 集、第 921 集、第 1015 集(以及更多)每段对话没有一句台词。

  • 等等。

如果我理解正确的话,许多网页的文本结构都不同,这使得我很难概括代码,除非我在这里遗漏了一些东西。

我的目标是将网页中的文本按原样获取到文本文件中,并以剧集名称作为文件名 - 即 0101.txt0310.txt 等就像 url 结尾扩展名一样。现在我已经通过 ctrl+a + ctrl+c + ctrl+v 手动收集了它们。我希望刮掉它,以便我可以自动化这个过程。现在,替代方法是使用 pyautogui 来实现此目的。但如果可能的话,我更喜欢网络抓取。我对 python 中的其他库(如果存在)持开放态度。

代码

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

最佳答案

您可以选择整个 HTML 标记文本以获取每个剧集链接内的所有内容,即 select_one('html').text。这看起来容易多了。

您可以使用带有 ^ 运算符的 css attribute = value 选择器(以声明属性值以 = 右侧的子字符串开头)来收集所有初始剧集链接即[href^='season']

当进行大量调用时,您可以重新使用 session 连接。我相信多处理在这里也可能是一个好主意。

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

然后您可以对检索到的文本执行您需要的操作。

关于python - 如何从多个网页中提取文本,其中某些页面在不同标签下有文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53525710/

相关文章:

python - 从 element.ResultSet 中提取项目

python - BeautifulSoup find_all() 不返回任何数据

python - 在 Python 中使用 lambda 时遇到问题

python - Scrapy 是否可以从原始 HTML 数据中获取纯文本?

python - 具有多个 Pandas DataFrame 的并排箱线图

javascript - 如何使用selenium从onclick javascript中提取url : Python

python - Beautifulsoup - 如何打开图片并下载它们

python - BeautifulSoup 获取给定类的 div 中所有不同的属性值

python - 如何分组 ndarray?

python - 在 intellij 中导入新的 python 模块的最佳方法是什么?