1

DOM を使用して Web サイトを解析しています。私はこれを解析しています:

<option value="A26JUYT14N57PY">Aleksander&#39;s Kindle Cloud Reader</option>
<option value="A13400OMTGFDRH">Aleksander&#39;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 を搭載した私の PC では、正常に動作します。

$attr1 = "A26JUYT14N57PY";
$value1 = "Aleksander&#39;s Kindle Cloud Reader";

$attr2 = "A13400OMTGFDRH";
$value2 = "Aleksander&#39;s Kindle for PC";

$attr3 = "add-new";
$value3 = "Register a new Kindle";

しかし、サーバーにスクリプトをアップロードすると、これは機能しなくなります (PHP のバージョンはわかりませんが、5.3.0 未満です)。結果は次のとおりです。

$attr1 = "A26JUYT14N57PY";
$value1 = "'";

$attr2 = "A13400OMTGFDRH";
$value2 = "'";

$attr3 = "add-new";
$value3 = "";

したがって、nodeValues の文字列からアポストロフィーだけが残っています - エンコーディングの問題だと思いますが、よくわかりません...奇妙なことは、nodeValues だけが間違っていて、値の属性は問題ないということです...

- - - - - - - 編集

コード解析 Web ページは次のとおりです (使用するクラスのソースは上にあります)。 $pageは、CURL によって返された Web ページの HTML ソース コードです。Amazon にログインした後であるため、直接の URL を示すことはできません。

$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 ヘッダーです (curl によって返されます)。

HTTP/1.1 200 OK Date: Fri, 11 May 2012 08:54:23 GMT Server: Server x-amz-id-1: 
0CHN2KA4VD4FTXF7K62J p3p: policyref=&quot;http://www.amazon.com/w3c/p3p.xml&quot;,CP=&quot;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 &quot; 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

- - - - - - - - - - - - 編集

http://simplehtmldom.sourceforge.netを使用しただけで、うまく機能します。

4

4 に答える 4

0

問題は'でなければなりません。DOMはXMLドキュメントで動作し、値に&文字を含めるにはCDATAセクションが必要になります。

'を削除し、機能するかどうかを確認します。もしそうなら、あなたはCDATAが必要です

于 2012-05-11T00:30:11.540 に答える
0

あなたが試すことができるいくつかのこと。そして、サーバーにアップロードした後、それらをすべて試してください。自分のマシンではありません。

  1. $dom->loadXML()とメソッドでテストし$dom->loadHTML()ます。
  2. Kolinkの回答またはこれを確認してください$value = $option->childNodes->item(0)->nodeValue;
  3. $array = simplexml_load_string($dom->saveXML($option))アレイに必要なものがあるかどうかを確認します。
  4. $ dom-> loadHTML(html_entity_decode($ html));を実行します。
于 2012-05-11T07:54:54.863 に答える
0

Try getting the nodeValue of the text node itself:

$value = $option->firstChild->nodeValue;
于 2012-05-11T00:34:18.480 に答える
0

PHP のバージョンよりも構成の違いだと思います (推測)。これは、DOMDocument がエンティティを置換する場合と置換しない場合があるためです (これは、PHP のさまざまな XML ライブラリを使用して DOM のような機能を取得し、DoS 脆弱性 (Billion Laughs や Quadratic Blowup など) を回避するにはどうすればよいですか?の DOMDocument コンポーネントを攻撃する際にも説明されています) 。 .

興味深い構成設定はLIBXML_NOENT次のとおりです。

$doc->loadXML($src, LIBXML_NOENT);

あなたはコードを共有していないので、これがあなたのコードに当てはまるかどうかはわかりません.

もう 1 つ確認する必要があるのは (私が経験したように)、ドキュメントのエンコーディングです。ドキュメントを再保存するか、適切に UTF-8 に変換すると役立つ場合があります。HTML を保存するときにエンティティを置換できる場合、通常は置換できます。

3 番目のオプションは、entitiy 要素を textnodes に置き換えるコードを自分で作成し、ドキュメントを再度正規化して、結合可能な textnodes を結合することです。

于 2012-05-11T08:02:38.583 に答える