Search code examples
beautifulsouppython-requestshtml-parsingdiscord.py

Send Discord Embed of Product Stock Parsed form HTML with BS4 and Requests


So I have the code:

import requests
import discord
from bs4 import BeautifulSoup

class MyClient(discord.Client):
    async def on_ready(self):
        print('Logged on as {0}!'.format(self.user))

    async def on_message(self, message):
        if (message.channel.id == 678447420643868674):
                if "test" in message.content:
                    r = requests.get('https://www.jimmyjazz.com/mens/footwear/adidas-solar-hu-nmd/BB9528')
                    soup = BeautifulSoup(r.text, 'html.parser')
                    embed = discord.Embed(color=0x00ff00)
                    embed.title = "test" 
                    for anchor_tag in soup.find_all(class_="box_wrapper")[0].findChildren():
                        if "piunavailable" in anchor_tag['class']:
                            embed.description = f"Size {anchor_tag.text} OOS"
                            await message.channel.send(embed=embed)
                        else:
                            embed.description = f"Size {anchor_tag.text}  in stock!"
                            await message.channel.send(embed=embed)
client = MyClient()
client.run('NjY2MDMyMDc0NjM3MTgwOTQ4.XkjBLg.I3dtsL2nkVh_bafTlycSwBApQfU')

And that sends the item stock as an embed for each size: https://gyazo.com/7a7c868d00a99fc3798a3c24feb9ea7e

How would I change the code to make it send for every size in one embed instead of an embed per size?

Thanks :)


Solution

  • Embeds in discord can have field which you can add with the embed.add_field() function embed.add_field(name="Field1", value="hi", inline=False)

    Embed have a few limits in size (copied from https://discordjs.guide/popular-topics/embeds.html#notes):

    • A field's name is limited to 256 characters and its value to 1024 characters
    • There can be up to 25 fields
    • In addition, the sum of all characters in an embed structure must not exceed 6000 characters

    Due to this you will have to likely split your product stock into multiple embed when it exceeds 25 field or 6000 character by having a counter for both and if it goes over resetting and sending message.

    Here is a part example (I've not tested it but logic should be correct)

    r = requests.get('https://www.jimmyjazz.com/mens/footwear/adidas-solar-hu-nmd/BB9528')
    soup = BeautifulSoup(r.text, 'html.parser')
    charCount = 0
    fieldCount = 0
    embed = discord.Embed(color=0x00ff00)
    embed.title = "test"
    for anchor_tag in soup.find_all(class_="box_wrapper")[0].findChildren():
        anchor_text = anchor_tag.text
        charCount += len(anchor_text)
    
        if charCount >=6000 or fieldCount >=25:
            charCount = len(anchor_text)
            fieldCount = 0
    
            await message.channel.send(embed=embed)
            embed = discord.Embed(color=0x00ff00)
            embed.title = "test"
    
        if "piunavailable" in anchor_tag['class']:
            embed.add_field(name= f"Size {anchor_text}", value="Out Of Stock")
        else:
            embed.add_field(name= f"Size {anchor_text}", value="In stock!")
    
        fieldCount +=1