Облако слов, созданное из URL-адресов в pandas df - одно облако слов для 220 статей вместо одного облака слов на статью - PullRequest
0 голосов
/ 18 июня 2020

У меня есть следующий фрейм данных:

    Title                      Source       Date              Link
    'Corona news'              NY Times     01-06-2020        nyt.com/corona_news
220 rows × 4 columns

Итак, у меня есть 220 ссылок на новостные статьи в этом df, которые я хочу использовать для создания wordcloud и размещения его через flask.

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

main.py

import base64
import feedparser
import io
import requests
import pandas as pd

from bs4 import BeautifulSoup
from wordcloud import WordCloud
from flask import Flask
from flask import render_template 

app = Flask(__name__)

BBC_FEED = pd.read_excel('All_news_corona.xlsx')
LIMIT = 20

class Article:
    def __init__(self, url, image):
        self.url = url
        self.image = image

@app.route("/")
def home():
    # feed = feedparser.parse(BBC_FEED)
    articles = []

    for article in BBC_FEED['Link'][:LIMIT]:
        print(article)
        text = parse_article(article)
        cloud = get_wordcloud(text)
        articles.append(Article(article, cloud))
    return render_template('home.html', articles=articles)

def parse_article(article_url):
    print("Downloading {}".format(article_url))
    r = requests.get(article_url)
    soup = BeautifulSoup(r.text, "html.parser")
    ps = soup.find_all('p')
    text = "\n".join(p.get_text() for p in ps)
    return text

def get_wordcloud(text):
    pil_img = WordCloud().generate(text=text).to_image()
    img = io.BytesIO()
    pil_img.save(img, "PNG")
    img.seek(0)
    img_b64 = base64.b64encode(img.getvalue()).decode()
    return img_b64

if __name__ == '__main__':
    app.debug = True
    app.run('127.0.0.1')

home. html

<html>
  <head>
    <title>News in WordClouds | Home</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

    <style type="text/css">
      body {padding: 20px;}
      img{padding: 5px;}
    </style>
  </head>

  <body>
    <h1>News Word Clouds</h1>
      <p>Too busy to click on each news article to see what it's about? Below you can see all the articles from the BBC front page, displayed as word clouds. If you want to read more about any particular article, just click on the wordcloud to go to the original article</p>
      {% for article in articles %}
        <a href="{{article.url}}"><img src="data:image/png;base64,{{article.image}}"></a>
      {% endfor %}
  </body>
</html>

Однако вместо того, чтобы использовать его для создания одного облака слов для каждой статьи, я хочу использовать его для создания одного облака слов, которое принимает входные данные из всех статей. У кого-нибудь есть быстрое исправление?

1 Ответ

1 голос
/ 18 июня 2020

Объедините все проанализированные тексты в одну строку, а затем передайте это вашей функции wordcloud:

all_texts = []

for article in BBC_FEED['Link'][:LIMIT]:
    all_texts.append(parse_article(article))

cloud = get_wordcloud(" ".join(all_texts))
articles.append(Article(url=None, image=cloud))  # no URL for the "meta-article"
return render_template('home.html', articles=articles)
...