Select and Download random image from Google

99封情书 提交于 2020-07-17 10:46:19

问题


Is there any example how I can search and download a random image from google? Using a random search string?

I want to use this image as steganography image and I want it to be a random one.

I am using C# with Visual Studio 2012.


回答1:


You probably don't want a random search string. You probably want random topics. Here is some code to help you out. First, create a list of topics:

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

Of course, you are free to change, add and remove as many topics as you wish. Next, we will create a function to retrieve the HTML code from a Google image search, randomly selecting one of our topics to search from:

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;
}

Once we have the HTML code, we need to parse out the img tags located underneath the images_table table and store the URL's of the images in a list:

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;
}

Our last function we need is to take an URL and have it download the image bytes into a byte array:

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;
}

Finally, we just need to tie it all together:

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);
}

UPDATE

I've gotten a few requests about this answer asking that I modify it so it loads the actual full size image rather than the thumbnail. I have modified my original code so that it loads the full size images now instead of the thumbnails.

First, like before, create a list of topics:

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

Of course you are free to change, add and remove as many topics as you wish. Next we will create a function to retrieve the HTML code from a Google image search, randomly selecting one of our topics to search from. GetHtmlCode() here is different from the GetHtmlCode() in the thumbnail version in that we must add an Accept and a UserAgent to the request or else Google won't give us the full size image URLs:

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;
}

The GetUrls() method was also rewritten because the HTML code we get back now is different from the HTML code we got back in our "thumbnail" version. It still parses out the URLs from the HTML code:

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;
}

Our last function we need is to take an URL and have it download the image bytes into a byte array. There is only one minor change in this function that's different from the "thumbnail" version. We had to change the number in ReadBytes() since our images will be larger now:

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;
}

Finally, we just need to tie it all together, like before:

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);
}



回答2:


Icemanind's answer mostly worked for me, though I had to rewrite 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;
    }

I also had to find a WPF alternative to Image.FromStream (source):

            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;
            }


来源:https://stackoverflow.com/questions/27846337/select-and-download-random-image-from-google

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!