Home > Software design >  How to parse values in a table cell with the same class name
How to parse values in a table cell with the same class name

Time:01-02

I am trying to get the values in a table cell with the same class name through the control WebView2

This Answer

it's useful to get a single value, but now I want to take in consideration that can happen to have more than a single value. The table full html code is:

<tbody data-v-39c7db2a=""><tr data-v-39c7db2a=""><td data-v-39c7db2a="" >12-31 19:57:47</td> <td data-v-39c7db2a="" >Limit</td> <td data-v-39c7db2a="" >KIBA/USDT</td> <td data-v-39c7db2a="" >
                                0.00003888
                            </td> <td data-v-39c7db2a="" ><span data-v-39c7db2a=""><!---->
                                    100
                                    KIBA
                                </span></td> <td data-v-39c7db2a="" >
                                0.00388800
                                
                                USDT
                            </td> <td data-v-39c7db2a="" >
                                0.0000%
                            </td> <td data-v-39c7db2a="" ><span data-v-39c7db2a="" >Cancel</span></td></tr><tr data-v-39c7db2a=""><td data-v-39c7db2a="" >12-31 19:43:51</td> <td data-v-39c7db2a="" >Limit</td> <td data-v-39c7db2a="" >KIBA/USDT</td> <td data-v-39c7db2a="" >
                                0.00003890
                            </td> <td data-v-39c7db2a="" ><span data-v-39c7db2a=""><!---->
                                    100
                                    KIBA
                                </span></td> <td data-v-39c7db2a="" >
                                0.00389000
                                
                                USDT
                            </td> <td data-v-39c7db2a="" >
                                0.0000%
                            </td> <td data-v-39c7db2a="" ><span data-v-39c7db2a="" >Cancel</span></td></tr></tbody>

while the code of each row in the table is:

<tr data-v-39c7db2a=""><td data-v-39c7db2a="" >12-31 19:57:47</td> <td data-v-39c7db2a="" >Limit</td> <td data-v-39c7db2a="" >KIBA/USDT</td> <td data-v-39c7db2a="" >
                                0.00003888
                            </td> <td data-v-39c7db2a="" ><span data-v-39c7db2a=""><!---->
                                    100
                                    KIBA
                                </span></td> <td data-v-39c7db2a="" >
                                0.00388800
                                
                                USDT
                            </td> <td data-v-39c7db2a="" >
                                0.0000%
                            </td> <td data-v-39c7db2a="" ><span data-v-39c7db2a="" >Cancel</span></td></tr>

The values I'm interested are the percentage like in this case 0.0000%. Since the class names are the same, how can I loop in order to get all of them?

CodePudding user response:

This requires some more javascript to work. However, once implemented it should work better. First save the following javascript to 'script.js' in your project's root directory (or a subdirectory, if you change the path in code). Make sure you select the file's properties and select Copy to output directory: Copy if newer. That copies the script file so WebView2 can find it.

Here's the javascript:

let GetOrders = function ()
{
    let doubles = [];
    let cells = document.querySelectorAll('div.ordersO.exchange-card.layout-r  td.text-right');
    let filteredArray = Array.from(cells).filter(function (value)
    {
        return value.textContent.includes('%') && value.nextElementSibling?.firstElementChild?.textContent.includes('Cancel');
    });
    filteredArray.forEach(function (value)
    {
        doubles.push( /[\d. -] /.exec(value.textContent)[0]);
    });
    return doubles;
};

Now that you have the javascript, you can implement the code in your form. Since I don't know Vb.net, I show the code in C# (should be easy to translate). Here's the entire form file:

using Newtonsoft.Json;
using Microsoft.Web.WebView2.Core;

namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private async void Form1_Load(object sender, EventArgs e)
        {
            await webView21.EnsureCoreWebView2Async();
            //webView21.CoreWebView2.Navigate(Path.Combine(Environment.CurrentDirectory, "html.html")); // Just my testing with your html
        }

        private async void WebView21_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            string script = File.ReadAllText("script.js");
            await webView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(script);
        }

        private async void Button1_Click(object sender, EventArgs e)
        {
            string json = await webView21.ExecuteScriptAsync("GetOrders()");
            decimal[] orders = JsonConvert.DeserializeObject<decimal[]>(json) ?? Array.Empty<decimal>();

            if (orders.Length == 0)
            {
                MessageBox.Show("No orders");
            }
            else
            {
                MessageBox.Show(String.Join(',', orders));
            }
        }
    }
}

Note that I use CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync - that injects the code in the page, so you can call it later.

Since ExecuteScriptAsync returns JSON, I use JsonSerializer.Deserialize<decimal[]> to create an array of decimal values.

This code will also work if there are no orders (returns an empty array).

Edit:

Changed to use Newtonsoft.Json.

Edit2:

Changed the javascript code to avoid duplicates!

  • Related