我正在使用DOM来解析一些网站。 我正在解析这个:
<option value="A26JUYT14N57PY">Aleksander's Kindle Cloud Reader</option>
<option value="A13400OMTGFDRH">Aleksander's Kindle for PC</option>
<optgroup label="----OR----" style="color:#999;font-style:normal;font-weight:normal"> </optgroup>
<option value="add-new">Register a new Kindle</option>
我的脚本是:
$dom->getElementsByTagName('option');
foreach($options as $option)
{
$attr = $option->getAttribute('value');
$value = $option->nodeValue;
}
在我的电脑上使用PHP 5.3.9,它可以正常工作:
$attr1 = "A26JUYT14N57PY";
$value1 = "Aleksander's Kindle Cloud Reader";
$attr2 = "A13400OMTGFDRH";
$value2 = "Aleksander's Kindle for PC";
$attr3 = "add-new";
$value3 = "Register a new Kindle";
但是当我在服务器上上传脚本时,它不再起作用了(我不确定它是什么PHP版本但是它&lt; 5.3.0)。结果是:
$attr1 = "A26JUYT14N57PY";
$value1 = "'";
$attr2 = "A13400OMTGFDRH";
$value2 = "'";
$attr3 = "add-new";
$value3 = "";
所以只有撇号从nodeValues中的字符串中留下 - 我认为它是带编码的东西,但我不确定......奇怪的是只有nodeValues是错的,值属性都没问题......
--------------编辑
这是代码解析网页(它使用的类的来源在上面)。
$page
是CURL返回的网页的html源代码 - 我无法直接提供您的网址,因为它是在登录亚马逊后的。
$dom = HtmlDomParser::getDomFromHtml($page);
$form = FormDomParser::getFormByName($dom,$this->amazon_config->buy_form_name);
if($form===false)
{
throw new AmazonParseException("Couldn't parse buy form");
}
$select = FormDomParser::getSelectByName($dom,$this->amazon_config->buy_deliveryoptions_name);
if($select === false)
{
throw new AmazonParseException("Couldn't parse options select");
}
$options = FormDomParser::getOptions($select);
$result = array();
foreach($options as $option)
{
//$value = $option->childNodes->item(0)->nodeValue;
//print_r($value);
$device_id = $option->getAttribute('value');
$device_name = $option->nodeValue;
echo $device_id.' = '.$device_name.'</br>';
}
HtmlDomParser
// simples class for parsing html files with DOM
class HtmlDomParser
{
// converts html (as string) to DOM object
public static function getDomFromHtml($html)
{
$dom = new DOMDocument;
$dom->loadHTML($html);
return $dom;
}
// gets all occurances of specified tag from dom object
// these tags must contain specified (in attributes array) attributes
public static function getTagsByAttributes($dom,$tag,$attributes = array())
{
$result = array();
$elements = $dom->getElementsByTagName($tag);
foreach($elements as $element)
{
$attributes_ok = true;
foreach($attributes as $key => $value)
{
if($element->getAttribute($key)!=$value)
{
$attributes_ok = false;
break;
}
}
if($attributes_ok)
{
$result[] = $element;
}
}
return $result;
}
}
FormDomParser
class FormDomParser
{
// gets form (as dom object) with specified name
public static function getFormByName($dom,$form_name)
{
$attributes['name'] = $form_name;
$forms = HtmlDomParser::getTagsByAttributes($dom,'form',$attributes);
if(count($forms)<1)
{
return false;
}
else
{
return $forms[0];
}
}
// gets all <input ...> tags from specified DOM object
public static function getInputs($dom)
{
$inputs = HtmlDomParser::getTagsByAttributes($dom,'input');
return $inputs;
}
// internal / converts array of Dom objects into assiosiative array
public static function convertInputsToArray($inputs)
{
$inputs_array = array();
foreach($inputs as $input)
{
$name = $input->getAttribute('name');
$value = $input->getAttribute('value');
if($name!='')
{
$inputs_array[$name] = $value;
}
}
return $inputs_array;
}
// gets all <select ...> tags from DOM object
public static function getSelects($dom)
{
$selects = HtmlDomParser::getTagsByAttributes($dom,'select');
return $selects;
}
// gets <select ...> tag with specified name from DOM object
public static function getSelectByName($dom,$name)
{
$attributes['name'] = $name;
$selects = HtmlDomParser::getTagsByAttributes($dom,'select',$attributes);
if(count($selects)<1)
{
return false;
}
else
{
return $selects[0];
}
}
// gets <option ...> tags from DOM object
public static function getOptions($dom)
{
$options = HtmlDomParser::getTagsByAttributes($dom,'option');
return $options;
}
// gets action value from form (as DOM object)
public static function getAction($dom)
{
$action = $dom->getAttribute('action');
if($action == "")
{
return false;
}
else
{
return $action;
}
}
}
---------编辑
这是我试图解析的http标头od网站(由curl返回):
HTTP/1.1 200 OK Date: Fri, 11 May 2012 08:54:23 GMT Server: Server x-amz-id-1:
0CHN2KA4VD4FTXF7K62J p3p: policyref="http://www.amazon.com/w3c/p3p.xml",CP="CAO
DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN
COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC " x-frame-options: SAMEORIGIN
x-amz-id-2: fFWynUQG0oqudmoDO+2FEraC2H+wWl0p9RpOyGxwyXKOc9u/6f2v8ffWUFkaUKU6
Vary: Accept-Encoding,User-Agent Content-Type: text/html; charset=ISO-8859-1
Set-cookie: ubid-main=190-8691333-9825146; path=/; domain=.amazon.com;
expires=Tue, 01-Jan-2036 08:00:01 GMT Set-cookie: session-id-time=2082787201l;
path=/; domain=.amazon.com; expires=Tue, 01-Jan-2036 08:00:01 GMT Set-cookie:
session-id=187-8097468-1751521; path=/; domain=.amazon.com; expires=Tue,
01-Jan-2036 08:00:01 GMT Transfer-Encoding: chunked
----------------------- edit
我刚刚使用了http://simplehtmldom.sourceforge.net,效果很好。
答案 0 :(得分:0)
问题必须是'。 DOM在XML文档上运行,你需要一个CDATA部分才能拥有&amp;值中的字符。
删除'并检查它是否有效。如果是,那么你需要CDATA
答案 1 :(得分:0)
尝试获取文本节点本身的nodeValue
:
$value = $option->firstChild->nodeValue;
答案 2 :(得分:0)
你可以尝试很少的东西。上传到您的服务器后再试一次。不是在你自己的机器上。
$dom->loadXML()
和$dom->loadHTML()
方法进行测试。$value = $option->childNodes->item(0)->nodeValue;
$array = simplexml_load_string($dom->saveXML($option))
并查看数组是否满足您的需求。答案 3 :(得分:0)
我会说(猜测)它的配置差异比PHP版本更多。这是因为有时DOMDocument会替换实体,有时也不会(在How can I use PHP's various XML libraries to get DOM-like functionality and avoid DoS vulnerabilities, like Billion Laughs or Quadratic Blowup?中攻击DOMDocument组件时也会讨论过这个问题。)
一个有趣的配置设置是LIBXML_NOENT
:
$doc->loadXML($src, LIBXML_NOENT);
您尚未共享任何代码,因此我不知道这是否适用于您。
你应该看一下(正如我所经历的那样),是文档的编码。重新保存文档/将其正确转换为UTF-8可能会有所帮助。如果在保存HTML时可以替换实体,则通常是。
第三个选项是您自己编写一些代码,用textnodes替换entitiy元素,然后再次规范化文档以组合可以组合的文本节点。