SeleniumでSVG要素を取得するには?

このSVGファイルをSeleniumで取得します。
タグ名やCSSセレクタでは普通に取得できますが、XPathはname属性で取得する必要があります。

SVGとは

ベクター形式の画像で、拡大縮小しても画質が劣化しないので、Webサイトでアイコンなどによく使われています。動きを付けること(アニメーション)も可能です。

Scalable Vector Graphicsは、XMLベースの、2次元ベクターイメージ用の画像形式の1つである。アニメーションやユーザインタラクションもサポートしている。SVGの仕様はW3Cによって開発され、オープン標準として勧告されている。

Wikipedia

タグ名で取得

左側の円(circle)と、真ん中の四角(rect)を取得する場合を考えます。
circleは2つあるので、find_elementsで取得します。

elements = driver.find_elements_by_tag_name('circle')
print(elements[0])
element = driver.find_element_by_tag_name("rect")
print(element)

<selenium.webdriver.remote.webelement.WebElement (session="ee8c17fcbfefea32aad366849c0c1401", element="9bd3b59d-d7e1-4ad8-8467-9f308f796123")>
<selenium.webdriver.remote.webelement.WebElement (session="ee8c17fcbfefea32aad366849c0c1401", element="9829c820-53f8-4f77-9463-676c6d60710e")>
List<WebElement> elements = driver.findElements(By.tagName("circle"));
System.out.println(elements.get(0));
WebElement element = driver.findElement(By.tagName("rect"));
System.out.println(element);

[[ChromeDriver: chrome on WINDOWS (f5bc3e99a3f5de866dfcbc01db9d146f)]
-> tag name: circle]
[[ChromeDriver: chrome on WINDOWS (f5bc3e99a3f5de866dfcbc01db9d146f)]
-> tag name: rect]
IList<IWebElement> elements = driver.FindElements(By.TagName("circle"));
Console.WriteLine(elements[0]);
IWebElement element = driver.FindElement(By.TagName("rect"));
Console.WriteLine(element);

Element (id = 51b25898-399c-47b2-9258-63a8e7a9d150)
Element (id = 74187421-5b72-4f86-a6ea-1ee46b53c937)
Dim elements = driver.FindElements(By.TagName("circle"))
Console.WriteLine(elements(0))
Dim element = driver.FindElement(By.TagName("rect"))
Console.WriteLine(element)

Element (id = ca17bc49-0f2d-492b-8a8e-0e6531964866)
Element (id = a98573f7-9aa4-44ac-8a98-daa647cdf9b4)
elements = driver.find_elements(:tag_name, "circle")
puts elements[0]
element = driver.find_element(:tag_name, "rect")
puts element

<Selenium::WebDriver::Element:0x00000000070af760>
<Selenium::WebDriver::Element:0x00000000070828c8>
var elements = await driver.findElements(By.tagName("circle"));
console.log(await elements[0]);
var element = await driver.findElement(By.tagName("rect"));
console.log(await element);

WebElement {
  driver_: Driver {
    session_: Promise { [Session] },
    executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
    fileDetector_: null,
    onQuit_: [Function: onQuit]
  },
  id_: Promise { '0da37849-8cf3-4c2c-8eef-0291784a9ada' }
}
WebElement {
  driver_: Driver {
    session_: Promise { [Session] },
    executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
    fileDetector_: null,
    onQuit_: [Function: onQuit]
  },
  id_: Promise { 'f60490bd-0013-48db-becb-2b04a1fe361d' }
}

find_elementsの戻り値は配列(List)で0から始まります。

CSSセレクタで取得

CSSセレクタやXPathでは、要素のカウントは1始まりです。

element = driver.find_element_by_css_selector('div > svg:nth-of-type(1) > circle')
print(element)
element = driver.find_element_by_css_selector('div > svg:nth-of-type(2) > rect')
print(element)

<selenium.webdriver.remote.webelement.WebElement (session="18352deaf5eb1507522d87c7075261b5", element="2fa6efc9-b6eb-4f5e-a423-b670cecb7d40")>
<selenium.webdriver.remote.webelement.WebElement (session="18352deaf5eb1507522d87c7075261b5", element="89beb406-46e1-45b9-9d4e-67bae938d65d")>
WebElement element = driver.findElement(By.cssSelector("div > svg:nth-of-type(1) > circle"));
System.out.println(element);
element = driver.findElement(By.cssSelector("div > svg:nth-of-type(2) > rect"));
System.out.println(element);

[[ChromeDriver: chrome on WINDOWS (3b37e931ef9483d603ce733162acd4d4)]
-> css selector: div > svg:nth-of-type(1) > circle]
[[ChromeDriver: chrome on WINDOWS (3b37e931ef9483d603ce733162acd4d4)]
-> css selector: div > svg:nth-of-type(2) > rect]
IWebElement element = driver.FindElement(By.CssSelector("div > svg:nth-of-type(1) > circle"));
Console.WriteLine(element);
element = driver.FindElement(By.CssSelector("div > svg:nth-of-type(2) > rect"));
Console.WriteLine(element);

Element (id = 26fb19b7-f284-48d4-afbc-46922ef7c889)
Element (id = 033e4e2f-f1bd-400d-9483-cd79f2cb6068)
Dim element = driver.FindElement(By.CssSelector("div > svg:nth-of-type(1) > circle"))
Console.WriteLine(element)
element = driver.FindElement(By.CssSelector("div > svg:nth-of-type(2) > rect"))
Console.WriteLine(element)

Element (id = d6b260c8-8cb1-4b63-8146-55962fe81c32)
Element (id = 63b8e201-604b-48c7-b782-fc56fa44afc1)
elements = driver.find_elements(:css, "div > svg:nth-of-type(1) > circle")
puts elements[0]
elements = driver.find_elements(:css, "div > svg:nth-of-type(2) > rect")
puts elements[0]

<Selenium::WebDriver::Element:0x00000000070f24e8>
<Selenium::WebDriver::Element:0x00000000070d1360>
var element = await driver.findElement(By.css("div > svg:nth-of-type(1) > circle"));
console.log(await element);
element = await driver.findElement(By.css("div > svg:nth-of-type(2) > rect"));
console.log(await element);

WebElement {
  driver_: Driver {
    session_: Promise {[Session]} ,
    executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
    fileDetector_: null,
    onQuit_: [Function: onQuit]
  },
  id_: Promise { '7cc197c2-fd40-4781-b224-ff40523b6778' }
}
WebElement {
  driver_: Driver {
    session_: Promise { [Session] },
    executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
    fileDetector_: null,
    onQuit_: [Function: onQuit]
  },
  id_: Promise { 'bb78c084-a655-4b98-b572-b9ad1636ee9e' }
}

CSSセレクタは、idやclassを指定することもできます。

element = driver.find_element_by_css_selector('#circle1')
print(element)
element = driver.find_element_by_css_selector('.cls1')
print(element)
WebElement element = driver.findElement(By.cssSelector("#circle1"));
System.out.println(element);
element = driver.findElement(By.cssSelector(".cls1"));
System.out.println(element);
IWebElement element = driver.FindElement(By.CssSelector("#circle1"));
Console.WriteLine(element);
element = driver.FindElement(By.CssSelector(".cls1"));
Console.WriteLine(element);
Dim element = driver.FindElement(By.CssSelector("#circle1"))
Console.WriteLine(element)
element = driver.FindElement(By.CssSelector(".cls1"))
Console.WriteLine(element)
elements = driver.find_elements(:css, "#circle1")
puts elements[0]
elements = driver.find_elements(:css, ".cls1")
puts elements[0]
var element = await driver.findElement(By.css("#circle1"));
console.log(await element);
element = await driver.findElement(By.css(".cls1"));
console.log(await element);

XPathで取得

タグ指定

XPathでSVGタグを指定するとエラーになります。

elements = driver.find_elements_by_xpath("//svg")
print(len(elements))
elements = driver.find_elements_by_xpath("//circle")
print(len(elements))
element = driver.find_element_by_xpath("//rect")

0 0 selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//rect"} (Session info: chrome=87.0.4280.66)
List<WebElement> elements = driver.findElements(By.xpath("//svg"));
System.out.println(elements.size());
elements = driver.findElements(By.xpath("//circle"));
System.out.println(elements.size());
WebElement element = driver.findElement(By.xpath("//rect"));

0 0 Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//rect"} (Session info: chrome=87.0.4280.66)
IList<IWebElement> elements = driver.FindElements(By.XPath("//svg"));
Console.WriteLine(elements.Count);
elements = driver.FindElements(By.XPath("//circle"));
Console.WriteLine(elements.Count);
IWebElement element = driver.FindElement(By.XPath("//rect"));

0 0 Exception thrown: 'OpenQA.Selenium.NoSuchElementException' in WebDriver.dll An unhandled exception of type 'OpenQA.Selenium.NoSuchElementException' occurred in WebDriver.dll Additional information: no such element: Unable to locate element: {"method":"xpath","selector":"//rect"} (Session info: chrome=87.0.4280.66)
Dim elements = driver.FindElements(By.XPath("//svg"))
Console.WriteLine(elements.Count)
elements = driver.FindElements(By.XPath("//circle"))
Console.WriteLine(elements.Count)
Dim element = driver.FindElement(By.XPath("//rect"))

0 0 Exception thrown: 'OpenQA.Selenium.NoSuchElementException' in WebDriver.dll An unhandled exception of type 'OpenQA.Selenium.NoSuchElementException' occurred in WebDriver.dll Additional information: no such element: Unable to locate element: {"method":"xpath","selector":"//rect"} (Session info: chrome=87.0.4280.66)
elements = driver.find_elements(:xpath, "//svg")
puts elements.count
elements = driver.find_elements(:xpath, "//circle")
puts elements.count
element = driver.find_element(:xpath, "//rect")

0 0 Uncaught exception: no such element: Unable to locate element: {"method":"xpath","selector":"//rect"} (Session info: chrome=87.0.4280.66)
var elements = await driver.findElements(By.xpath("//svg"));
console.log(await elements.length);
elements = await driver.findElements(By.xpath("//circle"));
console.log(await elements.length);
var element = await driver.findElement(By.xpath("//rect"));

0 0 UnhandledPromiseRejectionWarning: NoSuchElementError: no such element: Unable to locate element: {"method":"xpath","selector":"//rect"} (Session info: chrome=87.0.4280.66)
エラーメッセージ

no such element: Unable to locate element { Locater }

name指定

XPathの場合、タグ名でSVG要素を取得する場合は、タグをname属性に指定する必要があります。

print(driver.find_element_by_xpath("//*[name()='svg'][1]"))
print(driver.find_element_by_xpath("//*[name()='circle'][1]"))
print(driver.find_element_by_xpath("//*[name()='rect']"))

<selenium.webdriver.remote.webelement.WebElement (session="e5f1b5f51e7f373cece5fb385f7dace5", element="c96d1a12-ad07-4516-bb19-223bb2ac0311")>
<selenium.webdriver.remote.webelement.WebElement (session="e5f1b5f51e7f373cece5fb385f7dace5", element="c5c789a1-29c5-4fbe-a8bf-8ba8c1caeb37")>
<selenium.webdriver.remote.webelement.WebElement (session="e5f1b5f51e7f373cece5fb385f7dace5", element="c2a58cf6-e3c5-401e-a5d8-6f3bc4a8c19b")>
System.out.println(driver.findElement(By.xpath("//*[name()='svg'][1]")));
System.out.println(driver.findElement(By.xpath("//*[name()='circle'][1]")));
System.out.println(driver.findElement(By.xpath("//*[name()='rect']")));

[[ChromeDriver: chrome on WINDOWS (f58a0144b5b3a78c0fbf5410e944fb41)]
-> xpath: //*[name()='svg'][1]]
[[ChromeDriver: chrome on WINDOWS (f58a0144b5b3a78c0fbf5410e944fb41)]
-> xpath: //*[name()='circle'][1]]
[[ChromeDriver: chrome on WINDOWS (f58a0144b5b3a78c0fbf5410e944fb41)]
-> xpath: //*[name()='rect']]
Console.WriteLine(driver.FindElement(By.XPath("//*[name()='svg'][1]")));
Console.WriteLine(driver.FindElement(By.XPath("//*[name()='circle'][1]")));
Console.WriteLine(driver.FindElement(By.XPath("//*[name()='rect']")));

Element (id = af6f6893-449f-4882-a1ff-9dffe5d4e0e4)
Element (id = 66d1c839-da92-4891-981d-bc83fb25dc22)
Element (id = 6532df50-ea6c-43f2-b149-fe09c0e290e4)
Console.WriteLine(driver.FindElement(By.XPath("//*[name()='svg'][1]")))
Console.WriteLine(driver.FindElement(By.XPath("//*[name()='circle'][1]")))
Console.WriteLine(driver.FindElement(By.XPath("//*[name()='rect']")))

Element (id = 5ce87a2d-927d-4d9a-a868-79587a0200c5)
Element (id = b80b2b1c-3d13-43e5-901a-280a1fc0b93d)
Element (id = ddca8aeb-bd28-4752-8364-974c244a1d75)
puts driver.find_element(:xpath, "//*[name()='svg'][1]")
puts driver.find_element(:xpath, "//*[name()='circle'][1]")
puts driver.find_element(:xpath, "//*[name()='rect']")

<Selenium::WebDriver::Element:0x0000000007090450>
<Selenium::WebDriver::Element:0x000000000706b150>
<Selenium::WebDriver::Element:0x000000000705b890>
console.log(await driver.findElement(By.xpath("//*[name()='svg'][1]")));
console.log(await driver.findElement(By.xpath("//*[name()='circle'][1]")));
console.log(await driver.findElement(By.xpath("//*[name()='rect']")));

WebElement {
    driver_: Driver {
        session_: Promise { [Session] },
        executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
        fileDetector_: null,
        onQuit_: [Function: onQuit]
    },
    id_: Promise { 'a4fb18ab-7b53-4998-842c-44288795f700' }
}
WebElement {
    driver_: Driver {
        session_: Promise { [Session] },
        executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
        fileDetector_: null,
        onQuit_: [Function: onQuit]
    },
    id_: Promise { '22278d15-30a2-424f-9df0-90f45de81fc6' }
}
WebElement {
    driver_: Driver {
        session_: Promise { [Session] },
        executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
        fileDetector_: null,
        onQuit_: [Function: onQuit]
    },
    id_: Promise { '82994b61-4413-4330-aa66-3fd0df56921e' }
}

id、class指定

XPathでid属性やclass属性を指定しても取得できますが、タグを指定するとエラーとなります。

print(driver.find_element_by_xpath('//*[@id="circle1"]'))
print(driver.find_element_by_xpath('//*[@class="cls1"]'))

driver.find_element_by_xpath('//rect[@class="cls1"]')

<selenium.webdriver.remote.webelement.WebElement (session="67c3506efb74877fa2c56721c2f83f71", element="3e5c1aed-fe08-447b-8ee5-d26fa87ff87a")>
<selenium.webdriver.remote.webelement.WebElement (session="67c3506efb74877fa2c56721c2f83f71", element="e480076b-1f75-4446-a63c-1e2ec94be9ae")>

selenium.common.exceptions.NoSuchElementException: Message: no such element: 
Unable to locate element: {"method":"xpath","selector":"//rect[@class="cls1"]"}
  (Session info: chrome=87.0.4280.66)
System.out.println(driver.findElement(By.xpath("//*[@id='circle1']")));
System.out.println(driver.findElement(By.xpath("//*[@class='cls1']")));

driver.findElement(By.xpath("//rect[@class='cls1']"));

[[ChromeDriver: chrome on WINDOWS (473b9695af2ea76a17f076876dbd224e)]
-> xpath: //*[@id='circle1']]
[[ChromeDriver: chrome on WINDOWS (473b9695af2ea76a17f076876dbd224e)]
-> xpath: //*[@class='cls1']]

Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element:
{"method":"xpath","selector":"//rect[@class='cls1']"}
  (Session info: chrome=87.0.4280.66)
Console.WriteLine(driver.FindElement(By.XPath("//*[@id='circle1']")));
Console.WriteLine(driver.FindElement(By.XPath("//*[@clas='cls1']")));

driver.FindElement(By.XPath("//rect[@clas='cls1']"));

Element (id = 9a2b2369-b1d3-490a-915d-1807be05e257)
Element (id = 1abf80d7-0e72-4c73-bcfe-c1a96b41a0aa)

Exception thrown: &h39;OpenQA.Selenium.NoSuchElementException&h39; in WebDriver.dll
An unhandled exception of type &h39;OpenQA.Selenium.NoSuchElementException&h39; occurred in WebDriver.dll
Additional information: no such element: Unable to locate element: {"method":"xpath","selector":"//rect[@clas='cls1']"}
  (Session info: chrome=87.0.4280.66)
Console.WriteLine(driver.FindElement(By.XPath("//*[@id='circle1']")))
Console.WriteLine(driver.FindElement(By.XPath("//*[@class='cls1']")))

driver.FindElement(By.XPath("//rect[@class='cls1']"))

Element (id = 4c809693-0d50-4065-8f7f-ce99b8dc9d0e)
Element (id = ed3cd9e3-8ef1-42b5-aafa-cff6db4b0709)

Exception thrown: 'OpenQA.Selenium.NoSuchElementException' in WebDriver.dll
An unhandled exception of type 'OpenQA.Selenium.NoSuchElementException' occurred in WebDriver.dll
Additional information: no such element: Unable to locate element: {"method":"xpath","selector":"//rect[@class='cls1']"}
  (Session info: chrome=87.0.4280.66)
puts driver.find_element(:xpath, "//*[@id='circle1']")
puts driver.find_element(:xpath, "//*[@class='cls1']")

driver.find_element(:xpath, "//rect[@class='cls1']")

<Selenium::WebDriver::Element:0x00000000071393e8>
<Selenium::WebDriver::Element:0x00000000071084f0>

Uncaught exception: no such element: Unable to locate element: {"method":"xpath","selector":"//rect[@class='cls1']"}
  (Session info: chrome=87.0.4280.66)
console.log(await driver.findElement(By.xpath("//*[@id='circle1']")));
console.log(await driver.findElement(By.xpath("//*[@class='cls1']")));

await driver.findElement(By.xpath("//rect[@class='cls1']"));

WebElement {
    driver_: Driver {
        session_: Promise { [Session] },
        executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
        fileDetector_: null,
        onQuit_: [Function: onQuit]
    },
    id_: Promise { '88533efc-af00-4eb3-a22d-ca3f654e85fa' }
}
WebElement {
    driver_: Driver {
        session_: Promise { [Session] },
        executor_: Executor { w3c: true, customCommands_: [Map], log_: [Logger] },
        fileDetector_: null,
        onQuit_: [Function: onQuit]
    },
    id_: Promise { '9953497f-4d1d-4003-a542-1a9228df1717' }
}

UnhandledPromiseRejectionWarning: NoSuchElementError: no such element: Unable to locate element: {"method":"xpath","selector":"//rect[@class='cls1']"}
  (Session info: chrome=87.0.4280.66)

2021-02-04Selenium Tipsno such element,SVG,Xpath

Posted by sj