我对谷歌图片进行了一些搜索
结果是成千上万的照片。我正在寻找一个可以下载第一n
张图像的 shell 脚本,例如 1000 或 500。
我怎样才能做到这一点 ?
我想我需要一些高级正则表达式或类似的东西。我尝试了很多东西但无济于事,有人可以帮助我吗?
我对谷歌图片进行了一些搜索
结果是成千上万的照片。我正在寻找一个可以下载第一n
张图像的 shell 脚本,例如 1000 或 500。
我怎样才能做到这一点 ?
我想我需要一些高级正则表达式或类似的东西。我尝试了很多东西但无济于事,有人可以帮助我吗?
更新 4: PhantomJS 现已过时,我使用 Selenium 和 Chrome 无头在 Python 中创建了一个新脚本 google-images.py。有关更多详细信息,请参见此处:https ://stackoverflow.com/a/61982397/218294
更新 3:我修复了脚本以使用 phantomjs 2.x。
更新 2:我修改了脚本以使用 phantomjs。它更难安装,但至少它可以再次工作。http://sam.nipl.net/b/google-images http://sam.nipl.net/b/google-images.js
更新 1:不幸的是,这不再有效。现在似乎需要 Javascript 和其他魔法来查找图像的位置。这是雅虎图像搜索脚本的一个版本:http: //sam.nipl.net/code/nipl-tools/bin/yimg
原始答案:为此,我一起破解了一些东西。我通常会编写较小的工具并将它们一起使用,但您要求的是一个 shell 脚本,而不是三打。这是故意密集的代码。
http://sam.nipl.net/code/nipl-tools/bin/google-images
到目前为止,它似乎工作得很好。请让我知道您是否可以改进它,或者建议任何更好的编码技术(假设它是一个 shell 脚本)。
#!/bin/bash
[ $# = 0 ] && { prog=`basename "$0"`;
echo >&2 "usage: $prog query count parallel safe opts timeout tries agent1 agent2
e.g. : $prog ostrich
$prog nipl 100 20 on isz:l,itp:clipart 5 10"; exit 2; }
query=$1 count=${2:-20} parallel=${3:-10} safe=$4 opts=$5 timeout=${6:-10} tries=${7:-2}
agent1=${8:-Mozilla/5.0} agent2=${9:-Googlebot-Image/1.0}
query_esc=`perl -e 'use URI::Escape; print uri_escape($ARGV[0]);' "$query"`
dir=`echo "$query_esc" | sed 's/%20/-/g'`; mkdir "$dir" || exit 2; cd "$dir"
url="http://www.google.com/search?tbm=isch&safe=$safe&tbs=$opts&q=$query_esc" procs=0
echo >.URL "$url" ; for A; do echo >>.args "$A"; done
htmlsplit() { tr '\n\r \t' ' ' | sed 's/</\n</g; s/>/>\n/g; s/\n *\n/\n/g; s/^ *\n//; s/ $//;'; }
for start in `seq 0 20 $[$count-1]`; do
wget -U"$agent1" -T"$timeout" --tries="$tries" -O- "$url&start=$start" | htmlsplit
done | perl -ne 'use HTML::Entities; /^<a .*?href="(.*?)"/ and print decode_entities($1), "\n";' | grep '/imgres?' |
perl -ne 'use URI::Escape; ($img, $ref) = map { uri_unescape($_) } /imgurl=(.*?)&imgrefurl=(.*?)&/;
$ext = $img; for ($ext) { s,.*[/.],,; s/[^a-z0-9].*//i; $_ ||= "img"; }
$save = sprintf("%04d.$ext", ++$i); print join("\t", $save, $img, $ref), "\n";' |
tee -a .images.tsv |
while IFS=$'\t' read -r save img ref; do
wget -U"$agent2" -T"$timeout" --tries="$tries" --referer="$ref" -O "$save" "$img" || rm "$save" &
procs=$[$procs + 1]; [ $procs = $parallel ] && { wait; procs=0; }
done ; wait
特征:
有时间我会发布一个模块化版本,以展示它可以用一组 shell 脚本和简单的工具很好地完成。
我不认为你可以单独使用正则表达式来完成整个任务。这个问题有3个部分-
1 .提取所有图像的链接 -----> 不能用正则表达式完成。为此,您需要使用基于 Web 的语言。谷歌有 API 以编程方式执行此操作。看看这里和这里。
2 .假设您在第一步中成功使用了一些基于 Web 的语言,您可以使用以下正则表达式,它使用前瞻来提取确切的图像 URL
(?<=imgurl=).*?(?=&)
上面的正则表达式说 -从遇到符号之后开始抓取所有内容imgurl=
&
。有关示例,请参见此处,我在其中获取了搜索结果的第一张图片的 URL,并提取了图片 URL。
我是如何得出上述正则表达式的?通过检查在图像搜索中找到的图像的链接。
3 .现在您已经获得了图像 URL,使用一些基于 Web 的语言/工具来下载您的图像。
工作量这么大?为什么不使用批量图像下载器?它有 100 张图像限制。
并且需要为具有 Java 图像查看器的站点编码。
如果您想要图像的高度和宽度,请响应 Pavan Manjunath
(?<=imgurl=)(?<imgurl>.*?)(?=&).*?(?<=h=)(?<height>.*?)(?=&).*?(?<=w=)(?<width>.*?)(?=&)
您获得 3 个正则表达式组imgurl、height和width以及信息。
与其尝试解析 HTML(这非常困难并且可能会破坏),不如考虑@Paven在他的回答中突出显示的 API。
此外,考虑使用已经尝试做类似事情的工具。WGET (web-get) 具有类似蜘蛛的功能,用于跟踪链接(特别是针对指定的文件类型)。请参阅 StackOverflow 问题“我如何使用 wget 将所有图像下载到单个文件夹中”的答案。
正则表达式非常有用,但我不认为它是在这种情况下 - 记住正则表达式的口头禅:
有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。
——杰米·扎温斯基
Python 脚本:要从 Google 图片搜索下载全分辨率图片,目前它每次查询下载 100 张图片
from bs4 import BeautifulSoup
import requests
import re
import urllib2
import os
import cookielib
import json
def get_soup(url,header):
return BeautifulSoup(urllib2.urlopen(urllib2.Request(url,headers=header)),"html.parser")
query = raw_input("query image")# you can change the query for the image here
image_type="ActiOn"
query= query.split()
query='+'.join(query)
url="https://www.google.co.in/search?q="+query+"&source=lnms&tbm=isch"
print url
#add the directory for your image here
DIR="C:\\Users\\Rishabh\\Pictures\\"+query.split('+')[0]+"\\"
header={'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"
}
soup = get_soup(url,header)
ActualImages=[]# contains the link for Large original images, type of image
for a in soup.find_all("div",{"class":"rg_meta"}):
link , Type =json.loads(a.text)["ou"] ,json.loads(a.text)["ity"]
ActualImages.append((link,Type))
print "there are total" , len(ActualImages),"images"
###print images
for i , (img , Type) in enumerate( ActualImages):
try:
req = urllib2.Request(img, headers={'User-Agent' : header})
raw_img = urllib2.urlopen(req).read()
if not os.path.exists(DIR):
os.mkdir(DIR)
cntr = len([i for i in os.listdir(DIR) if image_type in i]) + 1
print cntr
if len(Type)==0:
f = open(DIR + image_type + "_"+ str(cntr)+".jpg", 'wb')
else :
f = open(DIR + image_type + "_"+ str(cntr)+"."+Type, 'wb')
f.write(raw_img)
f.close()
except Exception as e:
print "could not load : "+img
print e
我在这里重新发布我的解决方案我在以下问题上发布的原始解决方案 https://stackoverflow.com/a/28487500/2875380
我用它下载了 1000 张图片,它 100% 对我有用: atif93/google_image_downloader
下载后打开终端并安装 Selenium
$ pip install selenium --user
然后检查你的python版本
$ python --version
如果运行python 2.7
然后下载 1000 张披萨运行图像:
$ python image_download_python2.py 'pizza' '1000'
如果运行python 3
然后下载 1000 张披萨运行图像:
$ python image_download_python3.py 'pizza' '1000'
细分是:
python image_download_python2.py <query> <number of images>
python image_download_python3.py <query> <number of images>
查询是您要查找的图像名称,图像数量为 1000。在上面的示例中,我的查询是比萨饼,我想要 1000 张图像
使用这个库怎么样?谷歌图片下载
对于仍在寻找下载 100 张图像的体面方式的任何人,都可以使用此命令行参数代码。
github 上还有其他库 - 这看起来相当不错 https://github.com/Achillefs/google-cse
g = GoogleCSE.image_search('Ian Kilminster')
img = g.fetch.results.first.link
file = img.split('/').last
File.open(file,'w') {|f| f.write(open(img).read)}
`open -a Preview #{file}`