我正在尝试从imgnet链接中收集图像并将其保存在文件夹中。 使用urllib.urlretrieve,直到知道它工作得很好。 主要问题是何时该功能尝试访问DNS无法解析的主机。 我的链接是:http://www.fuminnaosu.com/image/person/kitamura.jpg
每个DNS无法解析时(可以删除),但仍在列表中。 Try&Except目前无法在我的项目中使用,是否有任何方法可以通过并继续收集而无需使用Try&Except? 我的错误是:
File "C:\Anaconda2\lib\socket.py", line 557, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
IOError: [Errno socket error] [Errno 11001] getaddrinfo failed
我的代码:
import cv2
import numpy as np
import os
import urllib
def get_images_to_dir():
images_list_lnk = 'http://image-net.org/api/text/imagenet.synset.geturls?wnid=n09618957'
images_url = urllib.urlopen(images_list_lnk)
urls = images_url.read()
img_typ = 'neg'
if not os.path.exists(img_typ):
os.mkdir(img_typ)
images_counter = 1
for url in urls.split('\n'):
img_name = img_typ+'/'+str(images_counter)+'.jpg'
urllib.urlretrieve(url, img_name)
img = cv2.imread(img_name, cv2.IMREAD_GRAYSCALE)
if (img is not None): # If connection success, but no image was found
img = cv2.resize(img, (100, 100))
cv2.imwrite(img_name, img)
images_counter += 1
完整的错误报告:
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.1.4\helpers\pydev\pydevd.py", line 1664, in <module>
main()
File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.1.4\helpers\pydev\pydevd.py", line 1658, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.1.4\helpers\pydev\pydevd.py", line 1068, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:/Users/xdavi/PycharmProjects/Face_and_eyes_detect/get-image-by-url.py", line 40, in <module>
get_images_to_dir()
File "C:/Users/xdavi/PycharmProjects/Face_and_eyes_detect/get-image-by-url.py", line 23, in get_images_to_dir
urllib.urlretrieve(url, img_name)
File "C:\Anaconda2\lib\urllib.py", line 98, in urlretrieve
return opener.retrieve(url, filename, reporthook, data)
File "C:\Anaconda2\lib\urllib.py", line 245, in retrieve
fp = self.open(url, data)
File "C:\Anaconda2\lib\urllib.py", line 213, in open
return getattr(self, name)(url)
File "C:\Anaconda2\lib\urllib.py", line 350, in open_http
h.endheaders(data)
File "C:\Anaconda2\lib\httplib.py", line 1038, in endheaders
self._send_output(message_body)
File "C:\Anaconda2\lib\httplib.py", line 882, in _send_output
self.send(msg)
File "C:\Anaconda2\lib\httplib.py", line 844, in send
self.connect()
File "C:\Anaconda2\lib\httplib.py", line 821, in connect
self.timeout, self.source_address)
File "C:\Anaconda2\lib\socket.py", line 557, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
IOError: [Errno socket error] [Errno 11001] getaddrinfo failed
答案 0 :(得分:0)
失败,因为地址查找失败。为什么您不能使用try除外块有零意义。
要解决此问题,您可以使用gevent异步greenlets(线程):
from gevent import monkey, spawn as gspawn, joinall
monkey.patch_all()
import cv2
import numpy as np
import os
import urllib
def get_images_to_dir(url):
img_typ = 'neg'
if not os.path.exists(img_typ):
os.mkdir(img_typ)
img_name = img_typ+'/'+str(images_counter)+'.jpg'
urllib.urlretrieve(url, img_name)
img = cv2.imread(img_name, cv2.IMREAD_GRAYSCALE)
if (img is not None): # If connection success, but no image was found
img = cv2.resize(img, (100, 100))
cv2.imwrite(img_name, img)
images_counter += 1
images_list_lnk = 'http://image-net.org/api/text/imagenet.synset.geturls?wnid=n09618957'
images_url = urllib.urlopen(images_list_lnk)
urls = images_url.read()
jobs = [gspawn(get_images_to_dir,url) for url in urls.split('\n')]
joinall(jobs)
这将使单个作业失败,但继续进行其余的作业,直到尝试了所有作业。您将需要修复代码以正确跟踪图像数量...老实说,我只计算最后的文件数。
答案 1 :(得分:0)
我不明白为什么您不使用try-try,因为要事先进行检查 将重复相同的过程。即 要检查主机是否可以访问,您必须访问它, 而urllib.urlretrieve()会这样做,当它无法访问时会引发异常。 这正是检查网址可用性的函数的方式 应该看起来。
现在,您可以进行半检查,即打开到端口80或443的TCP套接字,查看连接是否成功,然后关闭该套接字。 但是此方法不会检测文件本身是否存在。
所以,您要问的是:
from urllib2 import urlopen
import urllib
def check (url):
try:
u = urlopen(url)
u.close()
return True
except:
return False
URL = "http://adofiueaoiudsfoiu.com/iiiiddddd.img"
if check(URL):
urllib.urlretrieve(URL, "thefile.img")
您会看到这是多么愚蠢,与服务器联系两次却一无所获,而不仅仅是将urlretrieve()放入try块中。
因此,您应该做的是在try块中使用urllib2.urlopen(),如果成功,则读取数据并保存或执行您需要做的任何事情。 如果不成功,您将忽略所涉及的URL,仅此而已。 我强烈建议您按照上面的说明编写自己的检索函数,并避免使用urllib.urlretrieve()。