天道酬勤,学无止境

如何使用 Selenium 或 Protractor 获取 HTML 中嵌套元素的文本以进行自动化?(How do i get the text of a nested element in HTML for automation using Selenium or Protractor?)

问题

我有以下 HTML 代码。 我需要控制台日志或仅打印desc类文本 - “打印此”而不是量角器或硒中的spell类文本。

<span class="desc">
Print this
    <a class="new-link" href="#">
        <span class="spell">And not this</span>
    </a>
</span>

我试图getText()但它用下面的代码打印完整的语句 -

打印这个 而不是这个

在使用 Javascript 的量角器中:

element(by.css('.desc')).getText().then(function(text){
    console.log(text);
});

在使用 Java 的 Selenium 中:

System.out.println(driver.findElement(by.xpath('//*[@class=".desc"]')).getText());

我如何只打印文本的第一部分(即“打印这个”)?

任何建议或帮助将不胜感激? 谢谢。

回答1

ElementFinder.getText()在元素上调用innerHTML并删除前导和尾随空格,但innerHTML还包括任何嵌套级别的所有子元素。 DOM 中没有特殊属性只能获取一级文本,但可以自己实现。 DOM 中的文本也是一个节点,存储在 DOM 树中,与任何标签元素的方式相同,只是具有不同的类型和属性集。 我们可以通过属性Element.childNodes获取所有类型元素的一级子元素,然后迭代它们并只保留文本节点,然后连接它们的内容并返回结果。

在 Protractor 中,我决定向ElementFinder的原型添加一个自定义方法以使其易于使用,因此任何 Protractor 元素都将拥有它。 将这个扩展代码放在哪里取决于你,但我建议在你的测试之前将它包含在某个地方,也许在protractor.conf.js 中

protractor.ElementFinder.prototype.getTextContent = function () {
    // inject script on the page
    return this.ptor_.executeScript(function () {
        // note: this is not a Protractor scope

        // current element
        var el = arguments[0];
        var text = '';

        for (var i = 0, l = el.childNodes.length; i < l; i++) {
            // get text only from text nodes
            if (el.childNodes[i].nodeType === Node.TEXT_NODE) {
                text += el.childNodes[i].nodeValue;
            }
        }

        // if you want to exclude leading and trailing whitespace
        text = text.trim();

        return text; // the final result, Promise resolves with this value

    }, this.getWebElement()); // pass current element to script
};

此方法将返回一个 Promise,它使用text变量的值进行解析。 如何使用它:

var el = $('.desc');

expect(el.getTextContent()).toContain('Print this');

// or 

el.getTextContent().then(function (textContent) {
    console.log(textContent); // 'Print this'
});
回答2

我使用了 Michael 的解决方案并嵌入到我的测试规范中,而没有调用该函数。 如果经常需要使用,最好将其用作单独的功能。 但是,如果您想要内联解决方案,请按以下步骤操作 -

it("Get First part of text", function(){
    browser.executeScript(function () {
        var el = arguments[0], text = '';
        for (var i = 0, l = el.childNodes.length; i < l; i++)
            if (el.childNodes[i].nodeType === Element.TEXT_NODE)
                text += el.childNodes[i].nodeValue;
        return text.trim();
    },$('.desc').getWebElement()).then(function(text){
        //use expect statements with "text" here as needed
    });
});

希望能帮助到你。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何使用Selenium / Protractor设置HTML5 type =“ date”输入字段(例如,在Chrome中)?(How to set HTML5 type=“date” input fields (e.g. in Chrome) using Selenium/Protractor?)
    问题 我想更新一些HTML5日期表单字段的日期值(显示为mm / dd / yyyy,仅可修改数字部分): <input type="date"/> 在我的硒/量角器测试中。 我已经尝试过为此使用sendKeys ,但到目前为止(在Chrome上)尚未成功。 有没有办法使用sendKeys做到这sendKeys ? 还是其他方法可以做到? 回答1 在Mac上使用带有Protractor的Mac上的Chrome,以下方法对我有效。 范本(html5) <input type="date" placeholder="Due Date" ng-model="newLesson.dueDate"> 测试 this.newLessonDate = element( by.model('newLesson.dueDate') ); this.newLessonDate.sendKeys('01-30-2015'); 在输入日期格式为“ 01-30-2015”之前,我一直收到错误消息。 回答2 目前看来,最好的方法是在不触摸用户界面表示的情况下更新输入字段。 对于普通的Selenium,此方法似乎可以工作(随着UI更新以匹配): selenium.executeScript('document.getElementById("continuousFrom").value = "2050-01
  • 如何调试等待异步Angular任务的超时? 无法在角度页面上找到元素(How to debug timed out waiting for asynchronous Angular tasks? Failure to find elements on angular page occurring)
    问题 编辑:请注意,在@ ernst-zwingli的帮助下,我找到了问题的根源,因此,如果您遇到相同的错误,他指出的修复方法之一可能会为您提供帮助。 我的问题是量角器本身的一个已知问题,如果您认为可能是您自己,那么我会扩展我的步骤以在最初提出问题之后指出问题的根源。 我试图在使用angular-cli构建的Angular2(仅Angular)应用程序中使用Protractor。 我的问题:当browser.waitForAngularEnabled的默认设置为true时,找不到Angular应用程序页面上的元素(如“我相信我在一个角度页面上,并且希望量角器做到这一点很神奇”) 。 如果我将browser.waitForAngularEnabled设置为false则会发现它们很好(如“我不在一张有角度的页面上,并且想自己解决这个问题,坐在量角器”) 。 如何在我肯定的Angular页面上找到导致此问题的原因? 我有一个带有非Angular Auth0登录页面的产品,该页面可控制对使用Angular(准确地说是Angular 4.3.2)编写的产品的其余部分的访问。 我已成功遍历非Angular登录页面上的登录。 我将waitForAngularEnabled切换为false以方便非Angular登录。 在单击“提交”按钮后,我希望将其初始登录页面(Angular
  • 如何在量角器的输入上获取文本(How to getText on an input in protractor)
    问题 在量角器的文档中,我看到以下示例: describe('by model', function() { it('should find an element by text input model', function() { var username = element(by.model('username')); username.clear(); username.sendKeys('Jane Doe'); var name = element(by.binding('username')); expect(name.getText()).toEqual('Jane Doe'); }); 此处显而易见的是,您可以使用“ by.model”在输入框中设置值,但是如果您要查看输入框并查看其中的内容,则需要使用“ by.binding”。 我有一组代码(摘要)在其中执行: element(by.model('risk.name')).sendKeys('A value'); expect(element(by.model('risk.name')).getText()).toEqual('A value'); (在我的真实代码中,我保存了实体,然后在编辑模式下返回了该实体,并且我正在检查我的值是否已保存。但是它仍然归结为同一件事,并且此示例代码也存在相同的问题)。
  • python+Selenium——web自动化(浏览器对象及页面元素常用操作)
    目录 等待时间 多表单切换frame(iframe)切换 窗口切换 选择框操作 radio选择框 checkbox选择框 Select选择框 鼠标悬停 弹出对话框 Alert弹出框 Confirm弹出框 Prompt弹出框 截图 Cookie操作 滚动条 等待时间 在web中因为代码执行速度很快,但由于服务器请求需要时间和网络延迟等原因,在代码执行时,还未能等待页面元素出现就开始执行,这样会使操作不能找到元素使执行失败报错,定位元素的方法为find_element 时抛出异常,定位元素方法为find_elements时,返回空列表,这时可以通过设置等待时间来解决。由于具体的等待时长不好掌握,所以需要设置显示或隐式等待时长来解决。 显示等待WebDriverWait() 设置显示等待需要导入方法 from selenium.webdriver.support.ui import WebDriverWait 方法参数介绍 class WebDriverWait(object): def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None): ''' :param driver: 传入WebDriver实例 :param timeout:超时时间,等待的最长时间
  • 通过ID查找元素(Locating an element by id)
    问题 以下定位技术之间有什么区别? element(by.id("id")); element(by.css("#id")); element(by.xpath("//*[@id='id']")); browser.executeScript("return document.querySelector('#id');"); browser.executeScript("return document.getElementById('id');"); 而且,从性能角度来看,哪种方法是通过id定位元素的最快方法? 回答1 您的问题很难回答,肯定会给出一个结论性的答案。 实际上,我很想将此问题标记为“太宽泛”,其他答案和评论也支持该问题。 例如,仅使用您的element(by.id("id")); 。 纵观Selenium来源,大多数驱动程序只是获取您提供的ID,然后将其传递给有线协议: public WebElement findElementById(String using) { if (getW3CStandardComplianceLevel() == 0) { return findElement("id", using); } else { return findElementByCssSelector("#" + cssEscape(using)); } } 如您所知
  • 四 Python爬虫之selenium
    一 selenium的介绍 Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接调用浏览器,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏等。我们可以使用selenium很容易完成之前编写的爬虫,接下来我们就来看一下selenium的运行效果 1.1 下载配置chromedriver和selenium模块 下载chromedriver 下载地址:(下边这两个都可以) 1、http://chromedriver.storage.googleapis.com/index.html 2、https://npm.taobao.org/mirrors/chromedriver/ 注意: chromedriver的版本要与你的浏览器版本一致(大版本一致即可),否则不生效 我的浏览器版本: 打开驱动下载界面:https://npm.taobao.org/mirrors/chromedriver/ 这里有应该下载的对应的版本介绍: 根据我的浏览器版本是88.0.43243,所以下载的chromedriver版本: 配置驱动 下载后解压,将解压后的chromedriver.exe放在chrom浏览器安装路径里,然后把该路径添加到path环境变量里
  • 量角器-选择文本(Protractor - Selecting Text)
    问题 我在使用量角器选择某些文本时遇到了一些麻烦。 一点背景; 这是用于编写新闻文章的AngularJS CMS系统。 我要突出显示的文本位于页面大部分区域的文本区域内。 类似的应用程序是Google文档文档。 相信有了webdriver,我可以简单地使用一些东西来达到这种效果: browser.actions().keyDown(protractor.Key.CTRL).sendKeys('a').perform(); 但是,我在MAC上进行编码,尽管当前我们的测试是在SauceLabs的Windows框上运行的,但最终目标是迁移到MAC上来模拟我们的用户。 我尝试了类似的代码行,但是使用Command(或CMD),但是它不起作用,根据这篇文章,OSX不支持本机键事件。 我探索过的其他方法: 尝试在元素中单击三次以选择所有文本...但是我无法使它正常工作(有帮助吗?)。 由于鼠标光标必须位于文本上方才能突出显示所有文本,因此使情况变得复杂。 在本地计算机上双击该字段可以选择文本区域中的最后一个作品,但是在SauceLabs中,浏览器较小,因此可以选择其他单词。 使用起来感觉太脆了,因为在大多数机器上会有所不同。 将文本光标移动到文本区域的开头或结尾,按下Shift键并根据文本区域中的字符数按下向左或向右箭头键。 在此实现中,我无法将光标移动到文本字段的开头或结尾。 感谢您的阅读
  • 如何在Selenium WebDriver中获取元素的文本,而不包括子元素文本?(How to get text of an element in Selenium WebDriver, without including child element text?)
    问题 <div id="a">This is some <div id="b">text</div> </div> 获得“这是一些”并非易事。 例如,返回“ This is some text”: driver.find_element_by_id('a').text 在一般情况下,如何获得特定元素的文本而不包含其子元素的文本? (我在下面提供了一个答案,但是如果有人想出一个不太丑陋的解决方案,我将保留这个问题)。 回答1 这是一个通用的解决方案: def get_text_excluding_children(driver, element): return driver.execute_script(""" return jQuery(arguments[0]).contents().filter(function() { return this.nodeType == Node.TEXT_NODE; }).text(); """, element) 传递给函数的元素可以是从find_element...()方法获得的find_element...() (即它可以是WebElement对象)。 或者,如果您没有jQuery或不想使用它,则可以用以下代码替换上面函数的主体: return self.driver.execute_script(""" var parent =
  • 单击量角器端到端测试中隐藏元素的方法(A way of clicking on hidden elements in protractor end to end tests)
    问题 有没有一种方法可以单击子菜单中的隐藏值。 我希望能够做类似的事情 driver.findElement(protractor.By.xpath('/html/body/div/div/a')).mouseover.then(function() { ptor.findElement(protractor.By.className('name').getText().then(function(result) { expect(result).toBe('Me'); }); }); 当菜单项不可见时,或者我们目前受限于此。 如果无法做到这一点,那么目前有办法解决这个问题。 回答1 好吧,经过漫长而痛苦的搜索,试图找到这个问题的答案之后,我终于遇到了试图回答另一个问题的答案。 我找到的大多数文档都说明了我们必须以WebElement的形式使用Actions,然后将其强制转换为Javascript,并通过带有click action的数组形式将脚本元素传递给Javascript。 好吧,这里有相同的种类,但有一些修改。 describe('', function() { var ptor = protractor.getInstance(); var driver = ptor.driver; it('', function() { var hiddenElement =
  • 主张一个要素是集中的(Asserting an element is focused)
    问题 根据我如何断言一个元素是集中的? 线程,您可以通过切换到activeElement()来检查元素是否被聚焦,并断言这与您希望获得焦点的元素相同: expect(page.element.getAttribute('id')).toEqual(browser.driver.switchTo().activeElement().getAttribute('id')); 就我而言,当前关注的元素没有id属性。 我应该怎么做,而不要检查id ? 额外的问题:另外,从我的解决方案尝试中可以看出,我似乎无法期望/断言一个元素(或Web元素)作为一个完整的对象。 为什么? 我试过了: expect(page.element).toEqual(browser.driver.switchTo().activeElement()); 但是失败并出现一个我什至无法理解的错误-存在巨大的回溯(在控制台中滚动大约需要10分钟),但是内部没有用户友好的错误。 我也尝试过使用getWebElement() : expect(page.element.getWebElement()).toEqual(browser.driver.switchTo().activeElement()); 但这导致以下错误: 错误:期望通过WebElement参数调用,期望为Promise。 您是要使用.getText()吗?
  • 如何从父元素获取文本并从子元素中排除文本(C# Selenium)(How to get text from parent element and exclude text from children (C# Selenium))
    问题 是否可以仅从父元素而不是 Selenium 中的子元素获取文本? 示例:假设我有以下代码: <div class="linksSection> <a href="https://www.google.com/" id="google">Google Link <span class="helpText">This link will take you to Google's home page.</span> </a> ... </div> 在 C#(或任何语言)中,我将拥有: string linktext = driver.FindElement(By.CssSelector(".linksSection > a#google")).Text; Assert.AreEqual(linkText, "Google Link", "Google Link fails text test."); 但是,链接文本将包含“Google LinkThis link will take you to Google's home page”。 不做一堆字符串操作(例如获取所有子元素的文本并从父元素的结果文本中减去它),有没有办法只从父元素中获取文本? 回答1 这是selenium一个常见问题,因为您无法直接访问文本节点 - 换句话说,您的 XPath 表达式和 CSS
  • 使用量角器和硒将文件上传到隐藏的输入(Upload file to hidden input using protractor and selenium)
    问题 我有一个隐藏的文件输入字段,如下所示: <input type="file" id="fileToUpload-1827" multiple="" onchange="angular.element(this).scope().setFiles(this)" data-upload-id="1827" class="hidden-uploader"> 我希望能够将文件上传到此文件。 在量角器中执行此操作的正常方法是: ptor.findElement(protractor.By.css('.file-upload-form input')).sendKeys('/path/to/file') 但是因为输入元素不可见,所以出现错误。 我试过了: ptor.driver.executeScript("return $('.file-upload-form input')[0].removeClass('hidden-uploader');").then(function () { ptor.findElement(protractor.By.css('.file-upload-form input')).sendKeys('hello'); }) 但是得到了错误 UnknownError: $(...)[0].removeClass is not a function
  • 盘点——那些你必须知道的自动化测试面试题!
    问题1:Selenium是什么,流行的版本有哪些? 是一个开源的web自动化测试的框架,支持多种编程语言,支持跨浏览器平台进行测试。Selenium 1.0或Selenium RCSelenium 2.0或Selenium WebdriverSelenium 3.0 问题2:你如何从命令行启动Selenium RC? java -jar selenium-server.jar// 在浏览器中运行一套Selenese脚本java -jar selenium-server.jar -htmlSuite 问题3:在我的机器端口4444不是免费的。我怎样才能使用另一个端口? //你可以在运行selenium服务器时指定端口为 -Java -jar selenium-server.jar -port 5555 问题4:什么是Selenium Server,它与Selenium Hub有什么不同? Selenium Server是使用单个服务器作为测试节点的一个独立的应用程序。 Selenium hub代理一个或多个Selenium的节点实例。一个hub 和多个node被称为Selenium grid。运行SeleniumServer与在同一主机上用一个hub和单个节点创建de Selenium grid类似。 问题5:你如何从Selenium连接到数据库? Selenium是一个Web
  • Python爬虫 - Selenium(11)文件上传
    前言:大部分的文件上传功能都是用input标签实现,这样就完全可以把它看作一个输入框,可以通过send_keys()指定文件进行上传了。 本章中用到的关键方法如下: send_keys():上传文件或者输入文本 from selenium import webdriver import time driver = webdriver.Chrome() driver.get('http://file.yiyuen.com/file/') # 定位上传按钮,添加本地文件 driver.find_element_by_name("files").send_keys('D:\\test.txt') time.sleep(10) driver.quit() Selenium文集传送门: 标题简介Python爬虫 - Selenium(1)安装和简单使用详细介绍Selenium的依赖环境在Windows和Centos7上的安装及简单使用Python爬虫 - Selenium(2)元素定位和WebDriver常用方法详细介绍定位元素的8种方式并配合点击和输入、提交、获取断言信息等方法的使用Python爬虫 - Selenium(3)控制浏览器的常用方法详细介绍自定义浏览器窗口大小或全屏、控制浏览器后退、前进、刷新浏览器等方法的使用Python爬虫 - Selenium(4
  • web自动化你需要知道的
    web控件定位 XPATH定位 ‘//[@id=“s_tab”]//a[1]’ #定位到s_tab元素下面第一个a元素 '//[@id=“u”]/a’ 和’//*[@id=“u”]//a’ #这里面一个斜杠和两个斜杠的区别是:一个斜杠表示子元素,两个斜杠表示的是下面的子子孙孙的元素 css selector ‘#kw’ ‘#kw a’ #中间有一个空格(空格表示子子孙孙,如果是箭头表示子元素),表示id="kw"元素后面的a元素 ‘#kw a:nth-child(2)’ #表示a元素的父元素下面的第二个元素 ‘#kw a:nth-last-child(1)’ #表示a元素的父元素下面的倒数第一个元素 web控件交互官方文档: https://selenium-python.readthedocs.io/api.html ActionChains:执行PC端的鼠标点击,双击,右键,拖拽等事件,对H5页面操作无效 执行原理:调用ActionChains的方法时,不会被立即执行,而是将所有的操作,按顺序存放在一个队列里,当你调用perform()方法时,队列中的事件会依次执行 具体用法:执行PC端的鼠标点击,双击,右键,拖拽等事件 actions=ActionChains(driver) actions.move_to_element(element) actions.click
  • 如何在Selenium WebDriver中获得单个文本节点(How to get a single text node in Selenium WebDriver [duplicate])
    问题 这个问题已经在这里有了答案: 从节点获取文本(4个答案) 3年前关闭。 我想从标签中获取文本,但没有嵌套标签中的文本。 即在下面的示例中,我只想从<small>标记内部获取字符串183591 ,并从<span>标记中排除文本Service Request ID: 183591 这并不简单,因为<span>标签嵌套在<small>标签中。 WebDriver和XPath是否可能? 标签中的文本每次都会更改。 <div id="claimInfoBox" style="background-color: transparent;"> <div class="col-md-3 rhtCol"> <div class="cib h530 cntborder"> <h4 class="no-margin-bottom"> <p> <small style="background-color: transparent;"> <span class="text-primary" style="background-color: transparent;">Service Request ID:</span> 183591 </small> </p> <div class="border-bottom" style="background-color: transparent;"></div
  • 使用Python在Selenium WebDriver中获取WebElement的HTML源(Get HTML source of WebElement in Selenium WebDriver using Python)
    问题 我正在使用Python绑定来运行Selenium WebDriver: from selenium import webdriver wd = webdriver.Firefox() 我知道我可以像这样抓取网络元素: elem = wd.find_element_by_css_selector('#my-id') 而且我知道我可以通过以下方式获得整页的源代码: wd.page_source 但是有没有办法获得“元素来源”? elem.source # <-- returns the HTML as a string 用于Python的Selenium WebDriver文档基本上不存在,我在代码中看不到任何能够启用该功能的内容。 访问元素(及其子元素)的HTML的最佳方法是什么? 回答1 您可以读取innerHTML属性以获取元素内容的源,或者获取具有当前元素的源的outerHTML 。 Python: element.get_attribute('innerHTML') Java的: elem.getAttribute("innerHTML"); C#: element.GetAttribute("innerHTML"); 红宝石: element.attribute("innerHTML") JavaScript: element.getAttribute(
  • Python爬虫 - Selenium(5)鼠标事件
    前言:前边几篇文章也介绍过鼠标点击方法click(),但是这远远无法满足我们多样的需求,在 WebDriver 中, 关于鼠标操作的方法封装在 ActionChains 类中,其中包含右击、双击、拖动、鼠标悬停等等。 目录 一、常用方法二、代码示例 一、常用方法 函数名说明click(on_element=None)点击鼠标右键click_and_hold(on_element=None)点击鼠标左键,不松开release(on_element=None)在某个元素位置松开鼠标左键context_click(on_element=None)点击鼠标右键double_click(on_element=None)双击鼠标左键drag_and_drop(source, target)拖拽到某个元素然后松开drag_and_drop_by_offset(source, xoffset, yoffset)拽到某个坐标然后松开move_by_offset(xoffset, yoffset)鼠标从当前位置移动到某个坐标move_to_element(to_element)鼠标移动到某个元素move_to_element_with_offset(to_element, xoffset, yoffset)移动到距某个元素(左上角坐标)多少距离的位置perform()执行所有 ActionChains
  • 如何使用Webdriver和C#通过Selenium找到并单击嵌套在多个框架和框架集中的元素(How to locate and click on an element which is nested within multiple frame and frameset through Selenium using Webdriver and C#)
    问题 我有如下所示的html页面,我需要在类clslogin中单击Login。 我如何遍历以查找登录名。 我正在将C#与Selenium Webdriver一起使用。 使用XPath(/ html / body / div / table / tbody / tr [1] / td [3] / a),我无法控制Login类,始终找不到元素,并抛出错误。 谁能帮助我获得确切的xpath。 <html> <head></head> <frameset name="mytestTopFrame" rows="*"...... > <frame name="mytestTopsubframe" src="index.html" width="100%"......... > <html> <head></head> <frameset name="mytest" rows="70,20..."...... > <frame name="mytestsubframe" src="menu.html" width="100%"......... > <html> <body class="clsmenu" .......> <div align="left"> <table id="Title" ......> <tbody> <tr class="toptitle" ...> <td
  • 我如何从人类发出警报的页面中恢复“文本”,特别是在人类用户点击页面上的“警报”后,** ** [关闭]?(How do I recover the “text” from the page originating the alert, esp **after** the human user has *clicked* [dismiss] on the page's **alert**?)
    问题 基本上,当警报在JavaScript弹出,我可以dismiss()从蟒蛇完全确定它,通过调用selenium.webdriver.common.alert.Alert(browser).dismiss() 但是,如果“浏览器用户”通过使用鼠标单击[OK] (在屏幕上)来解除警报,则浏览器警报将“丢失空间”中的body.text不再从python中访问。 所以...如何在人类用户单击页面警报上的[dismiss]后,从发出警报的页面中恢复“文本”? 以下是提示和演示此问题的脚本... 仅供参考:原始代码的目的是允许浏览器用户在屏幕上进行测试并手动响应特定警报。 #!/usr/bin/env python import os,sys,time import selenium.webdriver import selenium.webdriver.support.expected_conditions print dict(python=sys.version,selenium=selenium.__version__) path=os.path.join(os.getcwd(),"hello_worlds.html") url="file:///"+path open(path,"w").write("""<HTML> <HEAD><TITLE>Head Title</TITLE