繁体   English   中英

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

[英]Efficient download of images from website with Python and selenium

免责声明:我没有网络抓取/ HTML / javascripts / css之类的背景,但是我知道一些Python。

我的最终目标是使用相关标签在ShapeNet网站中下载每3515个汽车视图的所有第4个图像视图。 在此处输入图片说明 例如,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 model_3dw_ bcf0b18a19bce6d91ad107790a9e2d51 ,我还需要提取它们都可以在以下位置找到的标签: 在此处输入图片说明 因此,我需要通过检查显示的每个图像来提取它。 然后,我需要切换页面(有22页),甚至可能在每个页面上向下滚动以确保我拥有所有内容。 其次,我不得不使用time.sleep两次,因为其他基于等待可点击的方法似乎无法按预期工作。

我有两个问题,第一个是显而易见的,这是正确的方法吗? 我觉得即使没有时间也可以很快,睡眠感觉很像人类会做的事情,因此如果确实要走,那么第二效率必须非常低下:我该如何编写double for loop on页面和项目能够有效地提取标签和模型ID?

编辑1:似乎:

l=browser.find_elements_by_xpath("//div[starts-with(@id,'model_3dw')]")

可能是迈向完成的第一步

编辑2:几乎在那里,但是代码充满了time.sleep。 仍然需要获取标签名称并遍历页面

编辑3:获得标记名称仍需要循环浏览页面,并将发布解决方案的初稿

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

您要单击每辆183533汽车,然后在弹出的iframe中下载第4张图片。 正确?

现在,如果是这种情况,让我们看一下您需要的第一个元素,即页面上装有所有汽车的元素。

因此,要获得第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.}

现在,对于第一页,您已经制作了一个循环,该循环将为上面的每辆车下载第4张图像。

由于您有多个页面,因此不能完全解决您的问题。 值得庆幸的是,第一页和/或最后一页的上一页和下一页页面导航均显示为灰色。

所以你可以说:

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

只要确保您捕获到元素不可点击的位置即可,因为元素将在最后一页显示为灰色。

与其抓取网站,不如考虑检查网页用来查询数据的URL,然后使用Python的“ requests”包直接从服务器直接发出API请求。 我不是该站点的注册用户,因此无法向您提供任何示例,但是描述shapenet.org网站的论文特别提到:

“为了方便地访问ShapeNet中包含的所有模型和注释数据,我们使用Apache Solr框架在所有3D模型及其相关注释上构建了一个索引。每个给定的3D模型都存储了一个注释包含在索引中作为单独的属性,可以通过简单的基于Web的UI轻松查询和过滤。此外,为了使研究人员可以方便地访问数据集,我们提供了批量下载功能。”

这表明只要您能够了解他们的查询语言所提供的内容,通过API进行所需的操作可能会更容易。 在他们的质量检查/论坛中进行搜索可能也很有用。

我想出了这个答案,这是一种有效的方法,但是我不知道如何删除多个time.sleep睡眠,直到有人发现更优雅的东西(也就是最后一个结尾时)我才会接受我的答案页面失败):

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()

tag_names=[]
page_count=0
while True:

    if page_count>0:
        browser.find_element_by_xpath("//a[@class='next']").click()
    time.sleep(2)
    wait.until(EC.presence_of_element_located((By.XPATH, "//div[starts-with(@id,'model_3dw')]")))  
    list_of_items_on_page=browser.find_elements_by_xpath("//div[starts-with(@id,'model_3dw')]")
    list_of_ids=[e.get_attribute("id") for e in list_of_items_on_page]

    for i,item in enumerate(list_of_items_on_page):
    #Page is also long to display iframe
        current_id=list_of_ids[i]
        element = wait.until(EC.element_to_be_clickable((By.ID, current_id)))
        car_image=browser.find_element_by_id(current_id)
        original_tag_name=car_image.find_element_by_xpath("./div[@style='text-align: center']").get_attribute("innerHTML")

        count=0
        tag_name=original_tag_name
        while tag_name in tag_names:            
            tag_name=original_tag_name+"_"+str(count)
            count+=1

        tag_names.append(tag_name)



        car_image.click()


        wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'viewerIframe')))

        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.%s.3']/img[@class='enlarge']"%current_id.split("_")[2])
        src = img.get_attribute('src')
        os.system("wget %s --no-check-certificate -O %s.png"%(src,tag_name))
        browser.switch_to.default_content()
        browser.find_element_by_css_selector(".btn-danger").click()
        time.sleep(1)

    page_count+=1

也可以从硒中导入NoSuchElementException,并使用try进行while True循环,除了摆脱任意的time.sleep。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM