Выберите и загрузите случайное изображение из Google

Есть ли пример, как я могу искать и загружать случайное изображение из Google? Используя случайную строку поиска?

Я хочу использовать это изображение в качестве стеганографического изображения, и я хочу, чтобы оно было случайным.

Я использую С# с Visual Studio 2012.


person Community    schedule 08.01.2015    source источник
comment
Вы действительно хотите случайную строку поиска? например HE8IHN96HV3? Это, скорее всего, не вернет совпадений с изображениями Google. Вместо этого вы можете выбрать случайное слово из словаря, найти его, а затем выбрать случайное изображение из всех результатов. Чтобы добиться этого на C#, ознакомьтесь с документацией API поиска Google по адресу googledotnet.codeplex.com   -  person Karnivaurus    schedule 08.01.2015
comment
Спасибо, Карниваурус. Я проверю.   -  person    schedule 08.01.2015
comment
Я мог просто видеть, что это приводит к некоторым ... ммм ... интересным результатам, я бы не стал помещать это в бизнес-приложение. :-П   -  person Ads    schedule 10.11.2017


Ответы (2)


Вероятно, вам не нужна случайная строка поиска. Вы, вероятно, хотите случайные темы. Вот некоторый код, который поможет вам. Сначала создайте список тем:

private readonly List<string> _topics = new List<string> {"dog", "car", "truck", "cat", "florida"};

Конечно, вы можете изменять, добавлять и удалять столько тем, сколько пожелаете. Далее мы создадим функцию для извлечения HTML-кода из поиска изображений Google, случайным образом выбирая одну из наших тем для поиска:

private string GetHtmlCode()
{
    var rnd = new Random();

    int topic = rnd.Next(0, _topics.Count - 1);

    string url = "https://www.google.com/search?q=" + _topics[topic] + "&tbm=isch";
    string data = "";

    var request = (HttpWebRequest)WebRequest.Create(url);
    var response = (HttpWebResponse)request.GetResponse();

    using (Stream dataStream = response.GetResponseStream())
    {
        if (dataStream == null)
            return "";
        using (var sr = new StreamReader(dataStream))
        {
            data = sr.ReadToEnd();
        }
    }
    return data;
}

Когда у нас есть код HTML, нам нужно проанализировать теги img, расположенные под таблицей images_table, и сохранить URL-адреса изображений в списке:

private List<string> GetUrls(string html)
{
    var urls = new List<string>();
    int ndx = html.IndexOf("class=\"images_table\"", StringComparison.Ordinal);
    ndx = html.IndexOf("<img", ndx, StringComparison.Ordinal);

    while (ndx >= 0)
    {
        ndx = html.IndexOf("src=\"", ndx, StringComparison.Ordinal);
        ndx = ndx + 5;
        int ndx2 = html.IndexOf("\"", ndx, StringComparison.Ordinal);
        string url = html.Substring(ndx, ndx2 - ndx);
        urls.Add(url);
        ndx = html.IndexOf("<img", ndx, StringComparison.Ordinal);
    }
    return urls;
}

Наша последняя функция, которая нам нужна, — это взять URL-адрес и загрузить байты изображения в массив байтов:

private byte[] GetImage(string url)
{
    var request = (HttpWebRequest)WebRequest.Create(url);
    var response = (HttpWebResponse)request.GetResponse();

    using (Stream dataStream = response.GetResponseStream())
    {
        if (dataStream == null)
            return null;
        using (var sr = new BinaryReader(dataStream))
        {
            byte[] bytes = sr.ReadBytes(100000);

            return bytes;
        }
    }

    return null;
}

Наконец, нам просто нужно связать все это вместе:

string html = GetHtmlCode();
List<string> urls = GetUrls(html);
var rnd = new Random();

int randomUrl = rnd.Next(0, urls.Count - 1);

string luckyUrl = urls[randomUrl];

byte[] image = GetImage(luckyUrl);
using (var ms = new MemoryStream(image))
{
    pictureBox1.Image = Image.FromStream(ms);
}

ОБНОВЛЕНИЕ

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

Сначала, как и раньше, создайте список тем:

private readonly List<string> _topics = new List<string> { "dog", "car", "truck", "cat", "florida" };

Конечно, вы можете изменять, добавлять и удалять столько тем, сколько пожелаете. Далее мы создадим функцию для извлечения HTML-кода из поиска изображений Google, случайным образом выбирая одну из наших тем для поиска. GetHtmlCode() здесь отличается от GetHtmlCode() в миниатюре тем, что мы должны добавить Accept и UserAgent к запросу, иначе Google не предоставит нам полноразмерные URL-адреса изображений:

private string GetHtmlCode()
{
    var rnd = new Random();

    int topic = rnd.Next(0, _topics.Count - 1);

    string url = "https://www.google.com/search?q=" + _topics[topic] + "&tbm=isch";
    string data = "";

    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Accept = "text/html, application/xhtml+xml, */*";
    request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";

    var response = (HttpWebResponse)request.GetResponse();

    using (Stream dataStream = response.GetResponseStream())
    {
        if (dataStream == null)
            return "";
        using (var sr = new StreamReader(dataStream))
        {
            data = sr.ReadToEnd();
        }
    }
    return data;
}

Метод GetUrls() также был переписан, потому что HTML-код, который мы получаем сейчас, отличается от HTML-кода, который мы получили в нашей «миниатюрной» версии. Он по-прежнему анализирует URL-адреса из HTML-кода:

private List<string> GetUrls(string html)
{
    var urls = new List<string>();

    int ndx = html.IndexOf("\"ou\"", StringComparison.Ordinal);

    while (ndx >= 0)
    {
        ndx = html.IndexOf("\"", ndx + 4, StringComparison.Ordinal);
        ndx++;
        int ndx2 = html.IndexOf("\"", ndx, StringComparison.Ordinal);
        string url = html.Substring(ndx, ndx2 - ndx);
        urls.Add(url);
        ndx = html.IndexOf("\"ou\"", ndx2, StringComparison.Ordinal);
    }
    return urls;
}

Наша последняя функция, которая нам нужна, — это взять URL-адрес и загрузить байты изображения в массив байтов. В этой функции есть только одно незначительное изменение, которое отличается от версии с миниатюрами. Нам пришлось изменить число в ReadBytes(), так как теперь наши изображения будут больше:

private byte[] GetImage(string url)
{
    var request = (HttpWebRequest)WebRequest.Create(url);
    var response = (HttpWebResponse)request.GetResponse();

    using (Stream dataStream = response.GetResponseStream())
    {
        if (dataStream == null)
            return null;
        using (var sr = new BinaryReader(dataStream))
        {
            byte[] bytes = sr.ReadBytes(100000000);

            return bytes;
        }
    }

    return null;
}

Наконец, нам просто нужно связать все вместе, как и раньше:

string html = GetHtmlCode();
List<string> urls = GetUrls(html);
var rnd = new Random();

int randomUrl = rnd.Next(0, urls.Count - 1);

string luckyUrl = urls[randomUrl];

byte[] image = GetImage(luckyUrl);
using (var ms = new MemoryStream(image))
{
    pictureBox1.Image = Image.FromStream(ms);
}
person Icemanind    schedule 08.01.2015
comment
@mafu - согласен! Ха-ха - person Icemanind; 01.09.2015
comment
Это довольно круто. Было бы лучше, если бы вы могли загрузить изображение в полном качестве, которое вы получаете, когда нажимаете на миниатюру. - person Julien; 16.02.2016
comment
Есть ли способ сделать это с изображениями полного качества? Маленькие настолько малы, что едва видны. - person MadBoy; 26.04.2016
comment
@Julien - я отредактировал свой ответ, чтобы обеспечить эту функциональность. - person Icemanind; 27.04.2016
comment
@MadBoy - я отредактировал свой ответ, чтобы обеспечить эту функциональность. - person Icemanind; 27.04.2016
comment
@Icemanind, теперь это выглядит красиво: D Спасибо. Извини за поздний ответ! - person MadBoy; 02.05.2016
comment
@Icemanind Я немного протестировал его, и иногда он дает сбой с ресурсами GDI, а иногда не загружает изображение. Знаете ли вы, в чем может быть проблема и как убедиться, что все приложение не падает из-за этого? - person MadBoy; 03.05.2016
comment
@MadBoy - Можете ли вы сказать мне конкретное сообщение об ошибке, которое вы получаете? И, если возможно, какие темы вы выбрали? - person Icemanind; 03.05.2016
comment
@Icemanind Привет, синтаксический анализ HTML не моя сильная сторона ... Около месяца назад метод GetUrls перестал работать, и я не знаю, как это исправить. Если у вас есть время, не могли бы вы обновить метод? Или подскажите что искать? - person Just A Minnion; 24.02.2020

Ответ Icemanind в основном работал на меня, хотя мне пришлось переписать Geturls:

    private List<string> GetUrls(string html)
    {
        var urls = new List<string>();

        string search = @",""ou"":""(.*?)"",";
        MatchCollection matches = Regex.Matches(html, search);

        foreach (Match match in matches)
        {
            urls.Add(match.Groups[1].Value);
        }

        return urls;
    }

Мне также пришлось найти альтернативу WPF Image.FromStream (источник):

            byte[] image = GetImage(luckyUrl);

            using (var stream = new MemoryStream(image))
            {
                var bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.StreamSource = stream;
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                bitmap.EndInit();
                bitmap.Freeze();

                this.img.Source = bitmap;
            }
person Jbjstam    schedule 30.09.2015