Return returns only the first value of the list (python)

Asked

Viewed 170 times

0

I’m creating a bot in the Discord that displays the films available in the cinema. It turns out I already had a Web Crawler in Python that did this, and I decided to put it to work on the bot by executing a command. However, when running it by the bot it only returned the first value of the list of movies, so I put the Return out of the for thinking it would solve, but now it returns only the second movie, instead of returning all (I would like to display all the available movies by the bot). How do I return all values of "t1" ?

# bot.py
import os
import random
import discord
from dotenv import load_dotenv
import bs4
from urllib.request import urlopen as uReq
from bs4 import BeautifulSoup as soup
import pandas as pd

load_dotenv()
TOKEN = os.getenv('token')
GUILD = os.getenv('Teste BOT')

client = discord.Client()

@client.event
async def on_ready():
    for guild in client.guilds:
        if guild.name == GUILD:
            break

print(
    f'{client.user} is connected to the following guild:\n'
    f'{guild.name}(id: {guild.id})\n'
)

members = '\n - '.join([member.name for member in guild.members])
print(f'Guild Members:\n - {members}')


@client.event
async def on_message(message):
    if message.author == client.user:
        return

def filmes():
    my_url = 'https://iguatemi.com.br/saocarlos/cinema/'
    uClient = uReq(my_url)
    page_html = uClient.read()
    uClient.close()
    page_soup = soup(page_html, "html.parser")

    for title in page_soup.select('li.node-readmore > a'):
        t1 = title.get('title')
    return t1


if message.content == 'filmes!':
    response = filmes()
    await message.channel.send(response)


client.run('Token')
  • t1 = title.get('title') - you are "overwriting" the value of t1 in the loop. If the idea is to return a list of items, you should do the append with all values obtained in title.get('title').

  • I posted a solution, however I was still editing some typos, but now this right, a check now and if you have any doubts just say, and the use of embed is very cool, you will enjoy

1 answer

3


there are many things I advise you to change in your code, let’s go to your first problem.

    for title in page_soup.select('li.node-readmore > a'):
        t1 = title.get('title')
    return t1

this way you will only return a result, how to fix? you can transform into a Generator object or create a list and bring back already as a formatted string, I will put a resolution down

    titulos = []
    for title in page_soup.select('li.node-readmore > a'):
        titulos.append(title.get('title'))
    return '\n'.join(titulos)

now something I advise to change in its structure

the Discord.py use the asynchronous methods, I advise rethink in its structure so that always use them because you can stop all the processes of its functioning because of a longer function taking all the advantage

another thing I advise you when sending the list of titles of the movies is to use Embed, you can take instructions by here, is very easy to use.


Edit

if you want you can try to create a Generator and if you prefer to send one title at a time

def filmes():
    my_url = 'https://iguatemi.com.br/saocarlos/cinema/'
    uClient = uReq(my_url)
    page_html = uClient.read()
    uClient.close()
    page_soup = soup(page_html, "html.parser")


    for title in page_soup.select('li.node-readmore > a'):
        yield title.get('title')

if message.content == 'filmes!':
    for response in filmes():
        await message.channel.send(response)

Edit 2

an example of what it would look like if you used Embed.

def filmes():
    my_url = 'https://iguatemi.com.br/saocarlos/cinema/'
    uClient = uReq(my_url)
    page_html = uClient.read()
    uClient.close()
    page_soup = soup(page_html, "html.parser")


    msg = discord.Embed(title=f'{" Lista de Filmes ":-^30}', colour=discord.Colour.dark_blue())
    for title in page_soup.select('li.node-readmore > a'):
        msg.add_field(name='Filme', value=title.get('title'), inline=False)
    return msg

if message.content == 'filmes!':
    msg = filmes()
    await message.channel.send(embed=msg)
  • It worked, thank you very much ! I managed to use the solutions of Edit 1 and 2, well complete the answer and helped a lot !

  • there is always a different way to do it, just choose the best in your perception, I passed 3 alternatives and hope it helps a lot and if it was useful do not forget to mark the posts as accepted.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.