有什么示例我可以从谷歌搜索和下载随机图像吗?使用随机搜索字符串?
我想将此图像用作隐写图像,我希望它是随机图像。
我在Visual Studio 2012中使用C#。
答案 0 :(得分:33)
您可能不想要随机搜索字符串。你可能想要随机主题。这里有一些代码可以帮到你。首先,创建一个主题列表:
private readonly List<string> _topics = new List<string> {"dog", "car", "truck", "cat", "florida"};
当然,您可以随意更改,添加和删除任意数量的主题。接下来,我们将创建一个函数来从Google图像搜索中检索HTML代码,随机选择我们要搜索的主题之一:
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
标记,并将图片的网址存储在列表中:
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" };
当然,您可以随意更改,添加和删除任意数量的主题。接下来,我们将创建一个函数来从Google图像搜索中检索HTML代码,随机选择我们要搜索的主题之一。 GetHtmlCode()
此处与缩略图版本中的GetHtmlCode()
不同,我们必须在请求中添加Accept
和UserAgent
,否则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);
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代码不同。它仍然从HTML代码中解析出URL:
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);
}
答案 1 :(得分:1)
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;
}
我还必须找到Image.FromStream(source)的WPF替代品:
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;
}