使用Python和selenium从网站高效下载图像

使用Python和selenium从网站高效下载图像,python,selenium,web-scraping,Python,Selenium,Web Scraping,免责声明:我没有任何web scraping/HTML/javascripts/css之类的背景,但我懂一点Python 我的最终目标是下载ShapeNet网站中每3515个汽车视图的所有第四个图像视图以及相关标签。 例如,3515对夫妇中的第一对是可以在该图片右侧的折叠菜单中找到的图像:(可通过单击第一页的第一项,然后在图像上加载),并带有相关标签“sport utility”,如第一张图片所示(第一辆车左上角) 为此,我在@DebanjanB的帮助下编写了一段代码,在第一张图片上单击spor

免责声明:我没有任何web scraping/HTML/javascripts/css之类的背景,但我懂一点Python

我的最终目标是下载ShapeNet网站中每3515个汽车视图的所有第四个图像视图以及相关标签。 例如,3515对夫妇中的第一对是可以在该图片右侧的折叠菜单中找到的图像:(可通过单击第一页的第一项,然后在图像上加载),并带有相关标签“sport utility”,如第一张图片所示(第一辆车左上角)

为此,我在@DebanjanB的帮助下编写了一段代码,在第一张图片上单击sport实用程序,打开iframe单击图片,然后下载第四张图片。完整的工作代码如下:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import os

profile = webdriver.FirefoxProfile()
profile.set_preference("network.proxy.type", 1)
profile.set_preference("network.proxy.socks", "yourproxy")
profile.set_preference("network.proxy.socks_port", yourport)
#browser = webdriver.Firefox(firefox_profile=profile)
browser = webdriver.Firefox()

browser.get('https://www.shapenet.org/taxonomy-viewer')
#Page is long to load
wait = WebDriverWait(browser, 30)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id='02958343_anchor']")))
linkElem = browser.find_element_by_xpath("//*[@id='02958343_anchor']")
linkElem.click()
#Page is also long to display iframe
element = wait.until(EC.element_to_be_clickable((By.ID, "model_3dw_bcf0b18a19bce6d91ad107790a9e2d51")))
linkElem = browser.find_element_by_id("model_3dw_bcf0b18a19bce6d91ad107790a9e2d51")
linkElem.click()
#iframe slow to be displayed
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'viewerIframe')))
#iframe = browser.find_elements_by_id('viewerIframe')
#browser.switch_to_frame(iframe[0])
element = wait.until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div[3]/h4")))
time.sleep(10)
linkElem = browser.find_element_by_xpath("/html/body/div[3]/div[3]/h4")
linkElem.click()



img = browser.find_element_by_xpath("/html/body/div[3]/div[3]//div[@class='searchResult' and @id='image.3dw.bcf0b18a19bce6d91ad107790a9e2d51.3']/img[@class='enlarge']")
src = img.get_attribute('src')


os.system("wget %s --no-check-certificate"%src)
这有几个问题。首先,我需要手动了解xpath模型\u 3dw\ustrong>bcf0b18a19bce6d91ad107790a9e2d51对于每个模型,我还需要提取标签,它们都可以在以下位置找到: . 所以我需要通过检查显示的每个图像来提取它。然后我需要切换页面(共22页),甚至可能在每一页上向下滚动以确保我拥有所有内容。其次,我不得不使用time.sleep两次,因为另一种基于等待可点击的方法似乎没有达到预期效果

我有两个问题第一个问题很明显这是正确的方法吗?我觉得,即使没有时间,这可能会非常快。睡眠这感觉非常像人类会做的事情,因此必须非常低效。第二,如果确实是这样的话:我如何才能在页面和项目上编写双for循环,以便能够有效地提取标记和模型id

编辑1:似乎:

l=browser.find_elements_by_xpath("//div[starts-with(@id,'model_3dw')]")
可能是走向完成的第一步

编辑2:差不多了,但代码中充满了时间。睡眠。仍然需要获取标记名并在页面中循环


编辑3:得到了标签名,仍然需要在页面中循环,并将发布解决方案的初稿

因此,让我尝试正确理解您的意思,然后看看我是否可以帮助您解决问题。我不懂Python,请原谅我的synthax错误

你想点击183533辆车中的每一辆,然后在弹出的iframe中下载第四张图片。对吗

现在如果是这样的话,让我们看看你需要的第一个元素,页面上所有的汽车都在上面的元素

因此,要获得第1页的所有160辆车,您需要:

elements = browser.find_elements_by_xpath("//img[@class='resultImg lazy']");
这将为您返回160个图像元素。这正是显示图像的数量(第1页)

然后你可以说:

for el in elements:
    {here you place the code you need to download the 4th image, 
     so like switch to iframe, click on the 4th image etc.}
现在,对于第一页,您已经做了一个循环,将为其上的每辆车下载第四张图像

这并不能完全解决您的问题,因为您有多个页面。谢天谢地,页面导航(上一页和下一页)在第一页和/或最后一页显示为灰色

所以你可以说:

browser.find_element_by_xpath("//a[@class='next']").click();

只要确保您捕捉到元素不可单击,因为元素将在最后一页变灰。

因此,让我试着正确理解您的意思,然后看看我是否可以帮助您解决问题。我不懂Python,请原谅我的synthax错误

你想点击183533辆车中的每一辆,然后在弹出的iframe中下载第四张图片。对吗

现在如果是这样的话,让我们看看你需要的第一个元素,页面上所有的汽车都在上面的元素

因此,要获得第1页的所有160辆车,您需要:

elements = browser.find_elements_by_xpath("//img[@class='resultImg lazy']");
这将为您返回160个图像元素。这正是显示图像的数量(第1页)

然后你可以说:

for el in elements:
    {here you place the code you need to download the 4th image, 
     so like switch to iframe, click on the 4th image etc.}
现在,对于第一页,您已经做了一个循环,将为其上的每辆车下载第四张图像

这并不能完全解决您的问题,因为您有多个页面。谢天谢地,页面导航(上一页和下一页)在第一页和/或最后一页显示为灰色

所以你可以说:

browser.find_element_by_xpath("//a[@class='next']").click();

如果元素不可单击,请确保捕获,因为元素将在最后一页变灰。

我想出了这个答案,哪种答案有效,但我不知道如何删除对time的几次调用。睡眠在有人找到更优雅的东西之前,我不会接受我的答案(当它到达最后一页的末尾时,也会失败):


你也可以从selenium中导入NoSuchElementException,并使用while True循环和try except,以消除任意的时间。睡眠。

我想出了这个答案,哪种方法有效,但我不知道如何消除对时间的多次调用。睡眠我不会接受我的答案,除非有人找到更优雅的东西(当它到达最后一页的末尾时,也会失败):


也可以从Sub导入NoUnCultEngExpRebug,使用一个while循环,除了取消任意的时间。睡眠。< /P> < P>而不是刮取站点,您可以考虑检查网页用于查询数据的URL,然后使用Python的请求包简单地从Services生成API请求。呃,我不是该网站的注册用户,所以我无法向您提供任何示例,但描述shapenet.org网站的文章特别提到:

“为方便访问所有模型和- 表示ShapeNet中包含的数据,我们构造 索引所有三维模型及其关联的annota- 使用ApacheSolr框架的复制。每个复制都存储了一个- 索引中包含给定三维模型的符号 作为一个单独的属性,可以轻松查询和筛选 通过一个简单的基于web的UI。此外,使 数据集便于研究人员访问,我们提供 批量下载功能。”

这表明,通过API做您想做的事情可能更容易,只要