nix*_*xda 12 powershell curl batch-file google-image-search
我正在寻找批处理或Powershell脚本,以使用本地图像作为输入在Google图像上搜索类似的图像.
我的研究到目前为止
使用URL而不是本地文件进行图像搜索的语法如下:
https://www.google.com/searchbyimage?image_url=TEST
其中TEST可以替换为您拥有的任何图像URL.
我使用cURL for windows和imgur作为临时图像保护程序.我能够通过批量上传文件到imgur.然后使用图片网址在Google上搜索类似的图片.
但我想知道是否可以不使用像imgur或任何其他在线图片服务的任何临时缓存.只是批量,卷曲,谷歌和我.
只是一个想法.VBS脚本是否能够使用本地文件作为输入在Google图像上进行搜索?
或者像Tineye这样的类似Web服务更适合这项任务?
此PowerShell代码段将打开谷歌图像搜索.
$IE= new-object -com InternetExplorer.Application
$IE.navigate2("https://www.google.com/imghp?hl=en")
while ($IE.busy) {
sleep -milliseconds 50
}
$IE.visible=$true
Run Code Online (Sandbox Code Playgroud)
接下来的步骤是获取某些按钮的ID并以编程方式单击它们以选择本地文件.但在这里,我没有足够的经验来实现这一目标.
lat*_*kin 20
好问题!我花了太多时间修补这个,但我觉得终于搞定了:)
简而言之,您必须上传图像的原始字节,嵌入并正确格式化以及其他一些内容images.google.com/searchbyimage/upload
.对该请求的响应将包含一个新URL,该URL将您发送到实际结果页面.
此函数将返回结果页面URL.你可以用它做任何你想做的事情,但只需在浏览器中打开结果,传递给它Start-Process
.
当然,Google可以随时更改此工作流程,因此不要指望此脚本永远有效.
function Get-GoogleImageSearchUrl
{
param(
[Parameter(Mandatory = $true)]
[ValidateScript({ Test-Path $_ })]
[string] $ImagePath
)
# extract the image file name, without path
$fileName = Split-Path $imagePath -Leaf
# the request body has some boilerplate before the raw image bytes (part1) and some after (part2)
# note that $filename is included in part1
$part1 = @"
-----------------------------7dd2db3297c2202
Content-Disposition: form-data; name="encoded_image"; filename="$fileName"
Content-Type: image/jpeg
"@
$part2 = @"
-----------------------------7dd2db3297c2202
Content-Disposition: form-data; name="image_content"
-----------------------------7dd2db3297c2202--
"@
# grab the raw bytes composing the image file
$imageBytes = [Io.File]::ReadAllBytes($imagePath)
# the request body should sandwich the image bytes between the 2 boilerplate blocks
$encoding = New-Object Text.ASCIIEncoding
$data = $encoding.GetBytes($part1) + $imageBytes + $encoding.GetBytes($part2)
# create the HTTP request, populate headers
$request = [Net.HttpWebRequest] ([Net.HttpWebRequest]::Create('http://images.google.com/searchbyimage/upload'))
$request.Method = "POST"
$request.ContentType = 'multipart/form-data; boundary=---------------------------7dd2db3297c2202' # must match the delimiter in the body, above
$request.ContentLength = $data.Length
# don't automatically redirect to the results page, just take the response which points to it
$request.AllowAutoredirect = $false
# populate the request body
$stream = $request.GetRequestStream()
$stream.Write($data, 0, $data.Length)
$stream.Close()
# get response stream, which should contain a 302 redirect to the results page
$respStream = $request.GetResponse().GetResponseStream()
# pluck out the results page link that you would otherwise be redirected to
(New-Object Io.StreamReader $respStream).ReadToEnd() -match 'HREF\="([^"]+)"' | Out-Null
$matches[1]
}
Run Code Online (Sandbox Code Playgroud)
用法:
$url = Get-GoogleImageSearchUrl 'C:\somepic.jpg'
Start-Process $url
Run Code Online (Sandbox Code Playgroud)
这里有一些更详细的信息.我基本上只是带你完成我拍摄的步骤.
首先,我只是继续进行本地图像搜索.
它发送给你的URL很长(在longcat的情况下约为1500个字符),但不足以完全编码图像(60KB).因此,您可以直接告诉它,它比简单地执行类似base64编码的操作更复杂.
接下来,我启动了Fiddler并查看了当您进行本地图像搜索时实际发生的情况.浏览/选择图像后,您会看到一些流量images.google.com/searchbyimage/upload
.详细查看该请求揭示了基本机制.
multipart/form-data
,您需要指定将不同字段(红色框)分隔的字符串.如果您使用Bing/Google,您会发现这multipart/form-data
是某种Web标准,但对于此示例而言,这无关紧要.encoded-image
字段中(绿色框).这里没有显示几个字段,在底部显示.它们并不是非常有趣.
一旦我弄清楚了基本的工作流程,只需编码就可以了.我只是尽可能地使用标准的.NET Web请求API复制了我在Fiddler中看到的Web请求.这个SO问题的答案演示了为了在Web请求中正确编码和发送正文数据所需的API.
从一些实验中,我发现你只需要我的代码(encoded_image
和image_content
)中包含的两个正文字段.浏览Web UI包含更多内容,但显然它们不是必需的.
更多实验表明,Fiddler中显示的其他标题或cookie都不是真正需要的.
出于我们的目的,我们实际上并不想访问结果页面,只获取指向它的指针.因此,我们应该设置AllowAutoRedirect
为$false
.这样,Google的302重定向就会直接发给我们,我们可以从中提取结果页面网址.
在编写此编辑时,我拍了拍我的额头并意识到Powershell v3具有Invoke-WebRequest
cmdlet,这可能会消除对.NET Web API调用的需求.不幸的是,经过10分钟修补后我无法正常工作,所以我放弃了.看起来像cmdlet编码数据的方式存在一些问题,尽管我可能错了.