如何使用 selenium webdriver (python) 选择、复制和粘贴元素中的所有内容

Posted

技术标签:

【中文标题】如何使用 selenium webdriver (python) 选择、复制和粘贴元素中的所有内容【英文标题】:How to select, copy and paste everything within an element using selenium webdriver (python) 【发布时间】:2021-06-14 05:31:42 【问题描述】:

这基本上就是我想要做的。我有 2 个网站,网站 A 包含我需要转移到网站 B 的数据。本质上

由于网站 A 出现故障,我正在将数据从网站 A 迁移到 B 很快。

我需要移动的是不仅仅是文本,它可以是文本、图像或超链接文本,还有一些我需要保留的格式内容。我认为最简单的方法是复制和粘贴而不是存储所有这些数据,这样我就可以将其插入网站 B,就像复制和粘贴一样。在我制作代码解决方案之前,他们只是从字面上复制和粘贴从 A 到 B 的所有内容。现在我已经在我的代码中实现了所有内容(获取链接和其他所需的内容),但我无法移动数据。所以基本上这就是我在尝试复制和粘贴数据之前正在做的事情。我正在使用 python 3。

            original_window = driver.current_window_handle
            driver.execute_script("window.open()")
            wait.until(EC.number_of_windows_to_be(2))
            driver.switch_to.window(driver.window_handles[1])
            actURL = a.getlink()
            driver.get(actURL)
            e = a.getactivitydata(driver)
            driver.close()
            driver.switch_to.window(driver.window_handles[0])

这里的 A 是一个自定义对象,它有方法 get link ,它返回指向我需要数据的网站 A 的链接。 A还包含方法getactivitydata,这是我要选择、复制和返回驱动程序的地方。方法代码是

def getactivitydata(self, driver):
    r = driver.page_source
    soup = BeautifulSoup(r, 'html.parser')  # Raw html obj
    ty = self.typef
    if ty == 'page':
        elem = driver.find_element_by_id("page-content")
        end = driver.find_element_by_class_name('course-nav')
        a = ActionChains(driver)
        #elem.send_keys("bar")
        a.move_to_element(elem)
        a.click_and_hold().perform()
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

        a.move_to_element(end)
        a.key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()

        #elem.send_keys(Keys.CONTROL, 'a')  # Select all
        #elem.send_keys(Keys.CONTROL, 'c')  # Copy
        return(elem)

    elif ty == 'quiz':
        pass
    elif ty == 'assign':
        pass
    elif ty == 'folder':
        pass
    elif ty == 'glossary':
        pass
    elif ty == 'resource':
        pass
    elif ty == 'forum':
        pass

ty 代表页面的类型,因为每个页面的处理方式都略有不同。我想要做的基本上是选择 HTML 中元素 id 为“page-content”的所有文本和图像。运行代码时(使用大量其他代码)我得到以下异常

selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable

在我尝试实际复制所需数据的行上引发了此异常。

虽然实际包含文本的元素是

(它已关闭>,这是我第一次发帖,我不知道如何让堆栈溢出关闭时显示)图像包含在 保留图像在文本中显示的顺序 以及如何获得

它们都属于的最小的 HTML 标记是

欢迎任何帮助或指导,我不反对使用复制/粘贴以外的其他方法,但我确实需要它在网站 B 上输出,就像它已被复制/粘贴一样。还有一些页面类型具有多个单独的元素,(如在线测验,您有问题 1、a)...、b...) ... 问题 2) 等...)谢谢!

【问题讨论】:

wget 实用程序可以拉取网站的完整镜像,跟踪所有链接并重建目录树。这会比抓取更有效。 @TimRoberts wget 的实现是如何工作的?从谷歌看起来它检索内容,所以我会检索特定元素的内容还是从整个页面检索,如果它是整个页面,如何解析该数据? 好吧,我很遗憾没有阅读所有内容。我阅读了消息的开头并得出结论,您想复制另一个网站。

【参考方案1】:

所以只是为了更新试图做同样事情的任何人。单击拖动不起作用,是什么

    a = ActionChains(driver)
    #elem.send_keys("bar")
    elem = driver.find_element(By.ID, "maincontent")
    #wait = WebDriverWait(driver, 10)
    #first = wait.until(EC.element_to_be_clickable(elem))
    a.move_to_element_with_offset(elem, 0, 0)
    a.key_down(Keys.SHIFT)
    a.double_click(elem).double_click(elem)
    end = driver.find_element_by_xpath('/html/body/div[1]/div[3]/div[3]')
    a.move_to_element(end).double_click(end)
    a.key_up(Keys.SHIFT)
    a.key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()

基本上我在这里所做的是在元素的开头和始终在其下方的另一个元素处按住 shift 和 quad click(我认为 3 在技术上会这样做),我尝试实现和偏移但无法使其工作

【讨论】:

以上是关于如何使用 selenium webdriver (python) 选择、复制和粘贴元素中的所有内容的主要内容,如果未能解决你的问题,请参考以下文章

Selenium & webdriver.io 如何使用 executeScript?

如何使用selenium webdriver来判断一个网页加载完毕

如何使用 C# 在 Selenium WebDriver (Selenium 2) 中最大化浏览器窗口?

如何在 ruby​​ 中使用 Selenium WebDriver (selenium 2.0) 客户端设置选项

如何在 Java 中使用 Selenium WebDriver (Selenium 2) 输入文本框?

如何使用Python避免Selenium Webdriver中的SSL认证错误?