我搜索谷歌图片
结果是成千上万的照片。我正在寻找一个将下载第一个n
图像的shell脚本,例如1000或500。
我该怎么做?
我想我需要一些高级正则表达式或类似的东西。我尝试了很多东西,但无济于事,有人可以帮我吗?
答案 0 :(得分:19)
更新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脚本和简单的工具很好地完成。
答案 1 :(得分:6)
我认为你不能单独使用正则表达式完成整个任务。这个问题有3个部分 -
1 。提取所有图片的链接-----&gt;不能用正则表达式完成。您需要使用基于Web的语言。谷歌有API以编程方式执行此操作。查看here和here。
2 。假设您使用某些基于Web的语言成功完成了第一步,您可以使用以下正则表达式使用前瞻提取精确的图像网址
(?<=imgurl=).*?(?=&)
以上正则表示 - 抓取所有内容从imgurl=
开始,直到遇到&
符号。 See here例如,我获取了搜索结果的第一张图片的网址并提取了图片网址。
我是如何到达上述正则表达式的?通过检查图像搜索中找到的图像的链接。
3 。现在您已获得图片网址,请使用一些基于网络的语言/工具下载您的图片。
答案 2 :(得分:2)
与使用regexp在shell中执行此操作相比,如果您使用可以实际解析HTML本身的内容(例如PHP's DOMDocument class),则可能会更容易。
如果您只使用shell并且需要啜饮图片网址,那么您可能不会完全失去运气。 Regular Expressions are inappropriate for parsing HTML,因为HTML不是regular language。但是,如果您的输入数据具有高度可预测性,您仍然可以顺利通过。 (无法保证这一点,因为Google会定期更新其产品和服务,而且无需事先通知。)
也就是说,在您在问题中提供的网址的输出中,每个图片网址似乎都嵌入到链接到/imgres?…
的锚点中。如果我们可以解析这些链接,我们可以收集他们需要的东西。在这些链接中,图片网址似乎以&imgurl=
开头。所以让我们抓住这个。
#!/usr/local/bin/bash
# Possibly violate Google's terms of service by lying about our user agent
agent="Mozilla/5.0 (X11; FreeBSD amd64; rv:12.0) Gecko/20100101 Firefox/12.0"
# Search URL
url="http://www.google.com/search?hl=en&q=panda&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&biw=1287&bih=672&um=1&ie=UTF-8&tbm=isch&source=og&sa=N&tab=wi&ei=qW4FUJigJ4jWtAbToInABg"
curl -A "$agent" -s -D- "$url" \
| awk '{gsub(/<a href=/,"\n")} 1' \
| awk '
/imgres/ {
sub(/" class=rg_l >.*/, ""); # clean things up
split($0, fields, "\&"); # gather the "GET" fields
for (n=1; n<=length(fields); n++) {
split(fields[n], a, "="); # split name=value pair
getvars[a[1]]=a[2]; # store in array
}
print getvars["imgurl"]; # print the result
}
'
我正在使用两个awk
命令,因为......好吧,我很懒,这是生成行的最快捷方式,我可以很容易地找到“imgres”字符串。人们可以花更多的时间来清理它并使它变得更优雅,但是收益递减的规律决定了这一点,就这一点而言。 : - )
此脚本返回一个URL列表,您可以使用其他shell工具轻松下载这些URL。例如,如果脚本名为getimages
,则:
./getimages | xargs -n 1 wget
请注意,当我使用您在问题中指定的搜索网址运行时,Google似乎只向我发送了83个结果(而非1000个)。这可能只是谷歌在我接近底部“扩展”页面(使用JavaScript)之前通常会向浏览器发送的第一页。 正确处理此问题的方法是根据Pavan的回答使用Google的搜索API,如果您每天进行超过100次搜索,则使用谷歌搜索他们的数据。
答案 3 :(得分:1)
工作量太大了?为什么不使用Bulk Image Downloader? 它有100个图像限制。
需要为拥有Java图像查看器的网站编码。
答案 4 :(得分:0)
不要试图解析HTML(非常难以破解),而应考虑@Paven在其答案中突出显示的API。
此外,请考虑使用已尝试执行类似操作的工具。 WGET(web-get)具有类似蜘蛛的功能,用于跟踪链接(特别是指定的文件类型)。请参阅StackOverflow问题'how do i use wget to download all images into a single folder'的答案。
正则表达式非常有用,但我不认为它是在这种背景下 - 记住正则表达式的口头禅:
有些人在面对问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。
- Jamie Zawinski
答案 5 :(得分:0)
有Pavan Manjunath的回应,如果你想要身高和高度图像宽度
(?<=imgurl=)(?<imgurl>.*?)(?=&).*?(?<=h=)(?<height>.*?)(?=&).*?(?<=w=)(?<width>.*?)(?=&)
您获得3个正则表达式组 imgurl , height &amp;带有信息的 width 。
答案 6 :(得分:0)
答案 7 :(得分:0)
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
答案 8 :(得分:0)
如何使用此库?google-images-download
对于仍在寻找下载100个图像的好方法的人,可以使用此命令行参数代码。
答案 9 :(得分:0)
我用它下载了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>
query 是您要查找的图像名称,图像数是1000。在上面的示例中,我的查询是披萨,我希望获得1000张图像>
答案 10 :(得分:-1)
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}`