DomCrawler组件

编辑该页面

警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 5.0,不再维护。

这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。

DomCrawler组件

DomCrawler组件简化了DOM HTML和XML文档的导航。

请注意

同时,DomCrawler组件不是用于操纵DOM或re-dumping HTML / XML。

安装

1
美元作曲家需要symfony / do欧宝娱乐app下载地址m-crawler

请注意

如果你安装这个组件之外的Symfony应用程序,你必须要求欧宝娱乐app下载地址供应商/ autoload.php文件在你的代码,使作曲家提供的类加载机制。读这篇文章为更多的细节。

使用

另请参阅

这篇文章解释了如何使用DomCrawler功能作为一个独立的组件在任何PHP应用程序。读了欧宝娱乐app下载地址Symfony功能测试篇文章来了解如何使用它在创建Symfony测试。欧宝娱乐app下载地址

履带类提供了方法来查询和操纵HTML和XML文档。

履带表示一组的一个实例DOMElement对象,该对象可以遍历节点,如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
使用欧宝娱乐app下载地址\组件\DomCrawler\履带;美元html=< < <“HTML”< !DOCTYPE html > < html > <身体> < p class = "消息" > Hello World !< / p > < p >你好履带!< /p>   HTML;< /span>美元履带=履带(美元html);foreach(美元履带作为美元domElement{var_dump ()美元domElement- >节点名);}

专业链接,图像形式类是用于交互的html链接,图片和表格您遍历html树。

请注意

DomCrawler将尝试自动修复你的HTML与官方的规范。例如,如果你窝< p >在另一个标签< p >标签,它将移动到父标签的兄弟姐妹。这是预期,HTML5规范的一部分。但是如果你得到意想不到的行为,这可能是一个原因。尽管DomCrawler并不意味着转储内容,您可以看到“固定”版本的HTML倾销它

请注意

如果你需要更好的支持HTML5的内容或想摆脱矛盾的PHP的DOM扩展,安装html5-php图书馆。DomCrawler组件将使用它时自动的内容有一个HTML5 doctype。

节点过滤

使用XPath表达式,可以选择文档中的特定节点:

1
美元履带=美元履带- >filterXPath (“子轴或self::阀体/ p”);

提示

DOMXPath:查询内部使用,实际执行XPath查询。

如果你喜欢在XPath CSS选择器,安装CssSelector组件。它允许您使用jQuery-like选择器来遍历:

1
美元履带=美元履带- >过滤器(“身体> p”);

一个匿名函数可以用来过滤与更复杂的标准:

1 2 3 4 5 6 7 8 9
使用欧宝娱乐app下载地址\组件\DomCrawler\履带;/ /……美元履带=美元履带- >过滤器(“身体> p”)- >减少(函数(履带美元节点,美元){/ /过滤其他节点返回(美元%2)= =0;});

删除一个节点匿名函数必须返回false。

请注意

所有过滤方法返回一个新的履带实例与过滤内容。

这两个filterXPath ()filter ()方法使用XML名称空间,可以显式地自动发现或注册。

考虑下面的XML:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
< ?xml version = " 1.0 " encoding = " utf - 8 " ? ><条目xmlns=“http://www.w3.org/2005/Atom”xmlns:媒体=“http://search.yahoo.com/mrss/”xmlns:欧美=“http://gdata.youtube.com/schemas/2007”><id>标签:youtube.com, 2008:视频:kgZRZmEc9j4< /id><欧美accessControl行动=“评论”许可=“允许”/ ><欧美accessControl行动=“videoRespond”许可=“主持”/ ><媒体:组><媒体:标题类型=“普通”>脊索动物——CrashCourse生物学# 24< /媒体:标题><欧美aspectRatio>宽屏< /欧美aspectRatio>< /媒体:组>< /条目>

这可以过滤的履带无需注册与命名空间别名filterXPath ():

1
美元履带=美元履带- >filterXPath (' / /默认值:输入/媒体:集团/ /欧美aspectRatio”);

filter ():

1
美元履带=美元履带- >过滤器(“默认媒体| |条目组次| aspectRatio”);

请注意

默认名称空间前缀“默认”注册。它可以改变setDefaultNamespacePrefix ()方法。

删除默认名称空间时加载的内容如果是唯一的名称空间的文档。为了简化XPath查询。

可以显式地注册的名称空间registerNamespace ()方法:

1 2
美元履带- >registerNamespace (“米”,“http://search.yahoo.com/mrss/”);美元履带=美元履带- >filterXPath (' / / m: / /欧美aspectRatio”);

验证如果当前节点匹配选择器:

1
美元履带- >匹配(“p.lorem”);

节点遍历

访问节点的位置列表:

1
美元履带- >过滤器(“身体> p”)- >eq (0);

获得第一个或最后一个节点当前的选择:

1 2
美元履带- >过滤器(“身体> p”)- >第();美元履带- >过滤器(“身体> p”)- >最后();

得到相同级别的节点作为当前的选择:

1
美元履带- >过滤器(“身体> p”)- >兄弟姐妹();

得到相同的级别节点之前或之后进行当前的选择:

1 2
美元履带- >过滤器(“身体> p”)- >nextAll ();美元履带- >过滤器(“身体> p”)- >previousAll ();

让所有的孩子或父节点:

1 2
美元履带- >过滤器(“身体”)- >孩子();美元履带- >过滤器(“身体> p”)- >父母();

得到所有的直接子节点匹配一个CSS选择器:

1
美元履带- >过滤器(“身体”)- >儿童(“p.lorem”);

获得第一个父(走向文档根)提供的相匹配的元素选择器:

1
美元履带- >最近的(“p.lorem”);

请注意

所有的遍历方法返回一个新的履带实例。

访问节点值

访问节点名(HTML标记名称)的当前选择的第一个节点(例如" p "或" div "):

1 2
/ /返回节点名(HTML标签名称)下的第一个子元素<身体>美元标签=美元履带- >filterXPath (' / /身体/ *)- >节点名();

访问当前选择的第一个节点的值:

1 2 3 4 5 6 7 8 9 10
/ /如果该节点不存在,打电话发短信()会导致异常美元消息=美元履带- >filterXPath (' / /身体/ p ')- >文本();/ /避免异常,通过论证文本()返回时,节点不存在美元消息=美元履带- >filterXPath (' / /身体/ p ')- >文本(默认文本内容的);/ /默认情况下,文本()修剪空白,包括内部的/ /(如。“foo巴兹\ n \ n酒吧”是作为“foo酒吧巴兹”)返回/ /将假作为第二个参数传递给返回原文不变美元履带- >filterXPath (' / /身体/ p ')- >文本(默认文本内容的,);

访问第一个节点的属性值的当前选择:

1
美元=美元履带- >filterXPath (' / /身体/ p ')- >attr (“类”);

从列表中提取属性和/或节点值的节点:

1 2 3 4
美元属性=美元履带- >filterXpath (' / /身体/ p ')- >提取([“_name”,“_text”,“类”]);

请注意

特殊的属性_text代表一个节点值,_name代表元素名称(HTML标记名称)。

在每个节点上调用匿名函数的列表:

1 2 3 4 5 6
使用欧宝娱乐app下载地址\组件\DomCrawler\履带;/ /……美元nodeValues=美元履带- >过滤器(“p”)- >每个(函数(履带美元节点,美元){返回美元节点- >文本();});

匿名函数接收节点(爬虫)和位置作为参数。结果是一个匿名函数调用返回的值的数组。

当使用嵌套的爬虫,当心filterXPath ()在履带的背景下评估:

1 2 3 4 5 6 7 8
美元履带- >filterXPath (“父”)- >每个(函数(履带美元parentCrawler,美元){/ /不这样做:直接的孩子不能被发现美元subCrawler=美元parentCrawler- >filterXPath (“sub-tag / sub-child-tag”);/ /这样做:指定父标签美元subCrawler=美元parentCrawler- >filterXPath (“父/ sub-tag / sub-child-tag”);美元subCrawler=美元parentCrawler- >filterXPath (“节点()/ sub-tag / sub-child-tag”);});

添加的内容

爬虫支持多种方式添加内容:

1 2 3 4 5 6 7 8 9 10
美元履带=履带(身体的< html > < / > < / html > ');美元履带- >addHtmlContent (身体的< html > < / > < / html > ');美元履带- >addXmlContent (' <根> <节点/ > < /根> ');美元履带- >addContent (身体的< html > < / > < / html > ');美元履带- >addContent (' <根> <节点/ > < /根> ',“text / xml”);美元履带- >add (身体的< html > < / > < / html > ');美元履带- >add (' <根> <节点/ > < /根> ');

请注意

addHtmlContent ()addXmlContent ()方法默认为utf - 8编码,但你可以改变这种行为,他们的第二个可选参数。

addContent ()猜测最好的方法根据给定的内容和默认字符集iso - 8859 - 1如果没有字符集可以猜到了。

爬虫的实现是基于DOM扩展,它也能够与本地交互DOMDocument,DOMNodeListDOMNode对象:

1 2 3 4 5 6 7 8 9 10
美元domDocument=\ DOMDocument ();美元domDocument- >loadXml (' <根> <节点/ > <节点/ > < /根>”);美元节点列表=美元domDocument- >getElementsByTagName (“节点”);美元节点=美元domDocument- >getElementsByTagName (“节点”)- >项目(0);美元履带- >addDocument (美元domDocument);美元履带- >addNodeList (美元节点列表);美元履带- >addnode ([美元节点]);美元履带- >addNode (美元节点);美元履带- >add (美元domDocument);

这些方法在履带最初是为了填充履带不打算被用来进一步操纵DOM(虽然这是可能的)。然而,由于履带是一组DOMElement对象,您可以使用任何方法或属性上可用DOMElement,DOMNodeDOMDocument。例如,您可以得到的HTML履带是这样的:

1 2 3 4 5
美元html=;foreach(美元履带作为美元domElement){美元html。=美元domElement- >ownerDocument- >saveHTML (美元domElement);}

或者你可以得到第一个节点使用的HTMLhtml ():

1 2 3 4 5
/ /如果该节点不存在,打电话来的html()会导致异常美元html=美元履带- >html ();/ /避免异常传递html()返回一个论点,当节点不存在美元html=美元履带- >html (的默认<强> HTML < /强>内容”);

或者你可以先的外HTML节点使用outerHtml ():

1
美元html=美元履带- >outerHtml ();

表达式求值

evaluate ()方法评估给定的XPath表达式。返回值取决于XPath表达式。如果表达式的求值结果为标量值(例如HTML属性),结果将返回的数组。如果表达式的求值结果为DOM文档,一个新的履带将返回实例。

这种行为是最好的例子说明:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47岁
使用欧宝娱乐app下载地址\组件\DomCrawler\履带;美元html=身体的< html > < > < span id =“- 100条”class = "文章" >第1条< / span > < span id =“- 101条”class = "文章" >第二条< / span > < span id =“- 102条”class = "文章" >第三条< / span > < /身体> < / html > ';美元履带=履带();美元履带- >addHtmlContent (美元html);美元履带- >filterXPath (' / /跨度(包含(@ id,“文章——“))”)- >评估(“substring-after (@ id,“-”));/ *结果:[0 = > ' 100 ',1 = > ' 101 ',2 = > ' 102 ',);* /美元履带- >评估(“substring-after(/ /跨度(包含(@ id,“文章——”)]/ @ id,“-”)”);/ *结果:[0 = >‘100’,]* /美元履带- >filterXPath (' / /跨度(@class =“文章”)”)- >评估(“数(@ id)”);/ *结果:[0 = > 1.0,1 = > 1.0,2 = > 1.0)* /美元履带- >评估(“计数(/ /跨度[@class = "文章"])”);/ *结果:(0 = > 3.0)* /美元履带- >评估(/ /跨[1]”);/ / S欧宝娱乐app下载地址ymfony \组件\ DomCrawler \爬虫实例

使用filter ()方法通过他们找到链接id属性和使用selectLink ()方法找到链接的内容(它也发现了可点击图片的内容alt属性)。

这两种方法都返回一个履带只有选中的链接实例。使用链接()方法来获取的链接对象表示的链接:

1 2 3 4 5 6 7 8 9 10 11 12
/ /首先,选择链接的id、类或内容……美元linkCrawler=美元履带- >过滤器(“#注册”);美元linkCrawler=美元履带- >过滤器(“.user-profile”);美元linkCrawler=美元履带- >selectLink (“登录”);/ /……然后,把链接对象:美元链接=美元linkCrawler- >链接();/ /或同时做这一切:美元链接=美元履带- >过滤器(“#注册”)- >链接();美元链接=美元履带- >过滤器(“.user-profile”)- >链接();美元链接=美元履带- >selectLink (“登录”)- >链接();

链接对象有几个有用的方法来获得更多的信息选择链接本身:

1 2
/ /返回正确的URI,可以用来制造另一个请求美元uri=美元链接- >getUri ();

请注意

getUri ()是特别有用,因为它清洁href值转换成它真正应该如何处理。例如,对于一个链接href = " # foo”,这将返回当前页面的完整URI后缀为# foo。返回从getUri ()总是一个完整的URI,您可以采取行动。

图片

找到一个图像的alt属性,使用selectImage方法对现有的爬虫。这返回一个履带只有选中的图像(s)实例。调用图像()给你一个特殊的图像对象:

1 2 3 4 5
美元imagesCrawler=美元履带- >selectImage (“小猫”);美元图像=美元imagesCrawler- >图像();/ /或这样做美元图像=美元履带- >selectImage (“小猫”)- >图像();

图像对象具有相同的getUri ()方法链接

形式

特殊待遇也给形式。一个selectButton ()履带上可用方法返回另一个相匹配的爬虫<按钮>< input type = " submit " >< input type = " button " >元素(或一个< img >元素里面)。中寻找给定的字符串作为参数id,alt,的名字,价值属性和元素的文本内容。

这种方法特别有用,因为您可以使用它来返回一个形式对象代表了按钮的形式生活在:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/ /按钮的例子:<按钮id =“my-super-button”类型=“提交”>我超级按钮> < /按钮/ /按钮的标签美元形式=美元履带- >selectButton (“我的超级按钮”)- >形式();/ /或按钮id (# my-super-button)如果按钮没有标签美元形式=美元履带- >selectButton (“my-super-button”)- >形式();/ /也可以过滤整个形式,例如表单有一个类属性:<形式类=“形成垂直”方法= " POST " >美元履带- >过滤器(“.form-vertical”)- >形式();/ /或“填补”表单字段数据美元形式=美元履带- >selectButton (“my-super-button”)- >形式([“名字”= >“瑞恩”]);

形式对象有很多非常有用的方法来处理形式:

1 2 3
美元uri=美元形式- >getUri ();美元方法=美元形式- >getMethod ();美元的名字=美元形式- >getName ();

getUri ()方法只是返回行动属性的形式。如果表单方法得到,那么模仿并返回浏览器的行为行动属性,后跟一个查询字符串的所有表单的值。

请注意

可选formactionformmethod按钮属性的支持。的getUri ()getMethod ()方法考虑这些属性总是返回正确的行动和方法取决于所使用的按钮的形式。

实际上你可以设置和获取值的形式:

1 2 3 4 5 6 7 8 9 10 11 12
/ /设置内部表单上的值美元形式- >setvalue ([“登记【用户名】”= >“欧宝娱乐app下载地址symfonyfan”,“登记(术语)”= >1]);/ /回来一组值,上面的“平”阵列像美元=美元形式- >getvalue ();/ /返回值像PHP会看到他们,/ /在“登记”是自己的数组美元=美元形式- >getPhpValues ();

使用多维领域:

1 2 3 4 5 6 7 8
输入name = <形> <“多[]”/ > < =输入的名字“多[]”/ > < =输入的名字“多(维)”/ > < =输入的名字“多(维)[]”值=“1”/ > < =输入的名字“多(维)[]”值=“2”/ > < =输入的名字“多(维)[]”值=“3”/ > < /形式>

通过一个数组的值:

1 2 3 4 5 6 7 8 9 10 11 12 13
/ /设置一个字段美元形式- >setvalue ([“多”= > [“价值”]]);/ /设置多个字段美元形式- >setvalue ([“多”= > [1= >“价值”,“维”= >“一个其他值”]]);/ /一次选择多个复选框美元形式- >setvalue ([“多”= > [“维”= > [1,3]/ /使用复选框的输入值来确定]]);

这是伟大的,但是它变得更好!的形式对象允许您与形式像浏览器交互,选择电台价值观,定时复选框和上传文件:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
美元形式(“登记【用户名】”]- >setValue (“欧宝娱乐app下载地址symfonyfan”);/ /检查或者取消复选框美元形式(“登记(术语)”]- >蜱虫();美元形式(“登记(术语)”]- >取消勾选();/ /选择一个选项美元形式(的登记(生日)(年)]- >选择(1984年);/ /选择许多选项从“多个”选择美元形式(“登记(利益)”]- >选择([s欧宝娱乐app下载地址ymfony的,“饼干”]);/ /假货文件上传美元形式(“登记(图)”]- >上传(“/道路/ / lucas.jpg”);

使用表单数据

做所有这一切又有什么意义呢?如果你在内部测试,您可以获取信息的提交的表单好像刚刚使用PHP值:

1 2
美元=美元形式- >getPhpValues ();美元文件=美元形式- >getPhpFiles ();

如果你使用外部HTTP客户端,您可以使用表单获取所有的信息您需要创建一个POST请求的形式:

1 2 3 4 5 6
美元uri=美元形式- >getUri ();美元方法=美元形式- >getMethod ();美元=美元形式- >getvalue ();美元文件=美元形式- >getfile ();/ /现在使用一些HTTP客户端和使用这些信息

一个集成的系统的一个很好的例子,它使用这个HttpBrowser提供的BrowserKit组件。它理解Symfony履带对象,并可以用欧宝娱乐app下载地址它来直接提交表单:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
使用欧宝娱乐app下载地址\组件\BrowserKit\HttpBrowser;使用欧宝娱乐app下载地址\组件\HttpClient\HttpClient;/ /使一个真正的请求到外部网站美元浏览器=HttpBrowser (HttpClient::create ());美元履带=美元浏览器- >请求(“得到”,“https://github.com/login”);/ /选择表单,填写一些值美元形式=美元履带- >selectButton (“登录”)- >形式();美元形式(“登录”]=“欧宝娱乐app下载地址symfonyfan”;美元形式(“密码”]=“anypass”;/ /提交给定的形式美元履带=美元浏览器- >提交(美元形式);

选择无效的选择值

默认情况下,选择字段(选择、广播)内部验证激活阻止你设置无效的值。如果你希望能够设置无效的值,您可以使用disableValidation ()方法在整个表单或特定字段(s):

1 2 3 4 5 6
/ /禁用验证为一个特定的领域美元形式(“国家”]- >disableValidation ()- >选择(“无效的价值”);/ /禁用验证整个形式美元形式- >disableValidation ();美元形式(“国家”]- >选择(“无效的价值”);
这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。