Jassim Rahma Ответов: 1

Захват названия сайта происходит слишком медленно


Привет,

Я использую приведенный ниже код, чтобы захватить название веб-сайта, и я также хочу позже захватить фотографию(ы) веб-сайта точно так же, как это делают Facebook, linkedin и twitter

Проблема с которой я столкнулся здесь заключается в том что он слишком медленный и занимает очень много времени чтобы показать заголовок в отличие от того когда вы делаете это с помощью facebook или linkedin например

Как я могу это исправить, пожалуйста?


Спасибо,
Джассим

Что я уже пробовал:

private async void Button_Clicked(object sender, EventArgs e)
{
    LabelWebsiteURL.Text = EntryURL.Text;

    HttpClient hc = new HttpClient();
    HttpResponseMessage response = await hc.GetAsync(new Uri(LabelWebsiteURL.Text, UriKind.Absolute));
    string source = await response.Content.ReadAsStringAsync();

    string title = Regex.Match(source, @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>", RegexOptions.IgnoreCase).Groups["Title"].Value;

    LabelWebsiteTitle.Text = title;
}

Richard MacCutchan

Как я уже говорил ранее, ваш код должен дождаться ответа удаленного сайта, а затем прочитать весь текст для регулярного выражения, чтобы найти то, что вы ищете. Вы не можете увеличить скорость удаленных сайтов с помощью кодирования.

0x01AA

"Вы не можете увеличить скорость удаленных сайтов с помощью кодирования": +5

Richard MacCutchan

Ха-ха, но что я знаю?

Gerry Schmitz

Вы когда-нибудь удосуживались проверить длину возвращаемых данных?

1 Ответов

Рейтинг:
1

Richard Deeming

Как сказал Ричард, вы не можете ничего сделать в своем коде, чтобы заставить удаленный сайт возвращать ответ быстрее.

Тем не менее, вы потенциально можете сократить небольшое количество времени и памяти, передавая ответ потоком и читая только до закрытия </head> метка.

Например:

public static class HttpContentExtensions
{
    public static async Task<string> ExtractHtmlHeadAsync(this HttpContent content)
    {
        if (content is null) throw new ArgumentNullException(nameof(content));
        
        using (var stream = await content.ReadAsStreamAsync())
        using (var reader = new StreamReader(stream))
        {
            int charsRead;
            char[] buffer = new char[1024];
            var sb = new StringBuilder();
            
            while ((charsRead = await reader.ReadBlockAsync(buffer, 0, buffer.Length)) != 0)
            {
                sb.Append(buffer, 0, charsRead);
                
                int index = FindClosingHeadIndex(sb);
                if (index != -1)
                {
                    sb.Length = index + 7;
                    break;
                }
            }
            
            return sb.ToString();
        }
    }
    
    private static int FindClosingHeadIndex(StringBuilder sb)
    {
        for (int index = 0; index < sb.Length - 6; index++)
        {
            if (sb[index] == '<'
                && sb[index + 1] == '/'
                && sb[index + 6] == '>'
                && (sb[index + 2] == 'h' || sb[index + 2] == 'H')
                && (sb[index + 3] == 'e' || sb[index + 3] == 'E')
                && (sb[index + 4] == 'a' || sb[index + 4] == 'A')
                && (sb[index + 5] == 'd' || sb[index + 2] == 'D'))
            {
                return index;
            }
        }
        
        return -1;
    }
}
private void Button_Clicked(object sender, EventArgs e)
{
    if (!Uri.TryCreate(EntryURL.Text, UriKind.Absolute, out var url))
    {
        MessageBox.Show("Please enter a valid URL!");
        return;
    }
    
    _ = LoadWebsiteTitleAsync(url);
}

private async Task LoadWebsiteTitleAsync(Uri url)
{
    LabelWebsiteURL.Text = url.ToString();
    
    var hc = new HttpClient();
    
    using (var response = await hc.GetAsync(url, HttpCompletionOption.ResponseContentRead))
    {
        string source = await response.Content.ExtractHtmlHeadAsync();
        Match match = Regex.Match(source, @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\s*\</title\>", RegexOptions.IgnoreCase);
        string title = match.Success ? match.Groups["Title"].Value : "# Untitled page #";
        LabelWebsiteTitle.Text = title;
    }
}
NB: Избегайте асинхронных методов void | Вы были взломаны[^]
Асинхронное Руководство - Дэвид Фаулер[^]