使用XPATH节点从产品中获取数据并将其插入表中 - php

我正在尝试从外部网站获取产品数据并将其插入特殊表中-每个找到的节点元素都需要导入到产品表中产品的相应列中!

找到1个产品属性并将其插入表中可以正常工作:

$product_names = $xpath->query("//div[contains(concat(' ', normalize-space(@class), ' '), ' product_description ')]/div/h3/a");
        if (!is_null($product_names)) {
            foreach ($product_names as $product_name) {
                $nodes = $product_name->childNodes;
                foreach ($nodes as $node) {
                    $import_product = 'INSERT INTO product_table (id, product_name) values ("","' . preg_replace('~\\s+\\S+$~', "", strip_tags(trim($node->nodeValue))) . '")';
                    mysql_query($import_supralift_name);
                }
            }
        }

但是产品具有许多属性,因此,我尝试获取此产品属性(在1个html元素中,因此我需要将其拆分成数组以用于不同的属性):

$types = $xpath->query("//div[contains(concat(' ', normalize-space(@class), ' '), ' product_description ')]/div/a/p");
        if (!is_null($types)) {
            foreach ($types as $type) {
                $nodes = $type->childNodes;
                foreach ($nodes as $node) {
                    list($typee,$power_unit) = explode(' / ', $node->nodeValue);
                    $import_type = 'INSERT INTO product_table (id, type, power_unit) values ("", "' . strip_tags(trim($typee)) . '", "' . strip_tags(trim($power_unit)) . '")';
                    mysql_query($import_type);
                }
            }
        }

简而言之-我需要从外部网站获取3个产品属性(当然,它们更多,只是想弄清楚什么是使它正常工作的最佳解决方案),然后将其插入我的数据库中,例如:

product_name_1 product_type_1 $power_unit_1
...
product_name_X product_type_X $power_unit_X

到目前为止,我尝试将第二个xpath部分放在第一个foreach中,但是并不能按需工作...
我应该尝试使用xpath节点(例如$ prodcuts = array(firstXpathNode,secondXpathNode等)来制作数组,并以这种方式工作,还是有更好,更正确的解决方案?

提前-TXN了解任何提示...

编辑:
以下是我尝试获取数据的示例HTML,这是针对产品的(每个产品都有用于显示数据的html):

<div class="single_product">
    <div data-section="featured_image">
        <a title="Unique_String" href="#">
            <div style="" data-section="image" class="image_in_fixed_ratio_wrapper">
                <div class="inner visible">
                    <img alt="Unique_String" src="image1.jpg" class="" style="">
                </div>
            </div>
        </a>
    </div>
    <div data-section="data">
        <div class="product_description">
            <div data-field="description_detail">
                <h3><a title="Unique_String" href="#">Product Name<div class="donotwantthistoinclude">New</div></a></h3>
                <a title="Unique_String" href="#"><p>Product Type / Product Power Unit</p></a>
                <div data-field="price">
                    <a title="Unique_String" href="#">5,000</a>
                </div>
                <div data-field="description">
                    <a title="Unique_String" href="#">
                        <span>Height (mm)</span> 2344
                 |
                                <span>Other attribute 1</span> Duplex
                 |
                                <span>Other attribute 2 (kg)</span>  1400
                 |
                                <span>Other attribute 3</span> 2014

                                 | <span>Other attribute X (h)</span> 772
                        <br><span>Location</span> D - 85716
                    </a>
                </div>
            </div>
        </div>
    </div>
</div>

参考方案

如果将第一个foreach中的产品名称分隔为变量,则可以基于产品名称构建相对的XPATH。我假设产品名称在页面上是唯一的。然后,第二个XPATH在页面上找到产品名称,然后在元素上走得更远。现在,将保证会有更好的XPATH查询来编写,以实现此目的,我自己还没有那种技能,但是我为您提供了一种方法。

因此,流程将类似于:

对于每个产品,获取名称,在新查询中插入名称,以获取该特定产品的类型和功率单位,解析变量,然后插入数据库。

警告

您正在使用危险且过时的SQL。请使用较新的mysqli_ *或PDO库通过准备好的语句访问数据库。我没有更新您的代码来反映这一点,对Google来说很容易。

但是,我确实在您现有的SQL中插入了product_name,以说明如何收集所有3个字段。

$product_names = $xpath->query("//div[contains(concat(' ', normalize-space(@class), ' '), ' product_description ')]/div/h3/a");
if (!is_null($product_names)) {
    foreach ($product_names as $product_name) {
        $nodes = $product_name->childNodes;
        foreach ($nodes as $node) {
            $productName = preg_replace('~\\s+\\S+$~', "", strip_tags(trim($node->nodeValue)));
            $xpath_relative = sprintf("//div[contains(concat(' ', normalize-space(@class), ' '), ' product_description ')]/div/h3/a[contains(text(),'%s')]/../../a/p",$productName);

            $types = $xpath->query($xpath_relative);
            if (!is_null($types)) {
                foreach ($types as $type) {
                    $types_nodes = $type->childNodes;
                    foreach ($types_nodes as $type_node) {
                        list($typee,$power_unit) = explode(' \'', $type_node->nodeValue);

                        // WARNING!!! SQL INJECTION BELOW!!!
                        $import_type = 'INSERT INTO product_table (id, type, power_unit, product_name) values ("", "' . strip_tags(trim($typee)) . '", "' . strip_tags(trim($power_unit)) . '", "' . $product_name . '")';
                        mysql_query($import_type);
                    }
                }
            }
        }
    }
}

编辑#2

我已将您的代码并在PHP Fiddle中与它一起运行,结果如下。我还根据提供的结构优化了XPATH查询,并提供了有关使用PDO的建议。只需根据需要填写更多属性。我将为您提供完整的代码,包括我使用的DOM和XPATH初始化,以便您自己动手。

<pre><?php

$domDoc = <<<EOF
<div class="single_product">
    <div data-section="featured_image">
        <a title="Unique_String" href="#">
            <div style="" data-section="image" class="image_in_fixed_ratio_wrapper">
                <div class="inner visible">
                    <img alt="Unique_String" src="image1.jpg" class="" style="" />
                </div>
            </div>
        </a>
    </div>
    <div data-section="data">
        <div class="product_description">
            <div data-field="description_detail">
                <h3><a title="Unique_String" href="#">Product Name<div class="donotwantthistoinclude">New</div></a></h3>
                <a title="Unique_String" href="#"><p>Product Type / Product Power Unit</p></a>
                <div data-field="price">
                    <a title="Unique_String" href="#">5,000</a>
                </div>
                <div data-field="description">
                    <a title="Unique_String" href="#">
                        <span>Height (mm)</span> 2344
                 |
                                <span>Other attribute 1</span> Duplex
                 |
                                <span>Other attribute 2 (kg)</span>  1400
                 |
                                <span>Other attribute 3</span> 2014

                                 | <span>Other attribute X (h)</span> 772
                        <br /><span>Location</span> D - 85716
                    </a>
                </div>
            </div>
        </div>
    </div>
</div>
EOF;
$dom = new DomDocument();
$dom->loadXML($domDoc);
$xpath = new DomXPath($dom);

$products = [];

$productUniqueQuery = "//div[@data-field='description_detail']/h3/a/@title";

$productUniqueNodes = $xpath->query($productUniqueQuery);
if (!is_null($productUniqueNodes)) {
    foreach ($productUniqueNodes as $productUniqueNode) {
        $product = [];
        $product["unique"] = $productUniqueNode->nodeValue;

        $productNameQuery = sprintf("//h3/a[@title='%s']/text()",$product["unique"]);
        $productNameNodes = $xpath->query($productNameQuery);
        $product["name"] = $productNameNodes[0]->nodeValue;

        $productImageQuery = sprintf("//img[@alt='%s']/@src",$product["unique"]);
        $productImageNodes = $xpath->query($productImageQuery);
        $product["imageURL"] = $productImageNodes[0]->nodeValue;

        $productTypeQuery = sprintf("//a[@title='%s']/p/text()",$product["unique"]);
        $productTypeNodes = $xpath->query($productTypeQuery);
        list($product["type"], $product["powerUnit"]) = explode(" / ", $productTypeNodes[0]->nodeValue);

        $productDescriptionQuery = sprintf("//div[@data-field='description']/a[@title='%s']/child::node()",$product["unique"]);
        $productDescriptionNodes = $xpath->query($productDescriptionQuery);
        $description = "";
        foreach ($productDescriptionNodes as $productDescriptionNode) {
            $nodeText = preg_replace("/\s*\|/","",trim($productDescriptionNode->nodeValue));
            if($nodeText == "" || $productDescriptionNode->nodeType === 3){
                continue;
            }

            $product[$nodeText] = preg_replace("/\s*\|/","",trim($productDescriptionNode->nextSibling->nodeValue));
        }
        $products[$product["unique"]] = $product;
    }
}


try {
    $db = new PDO("mysql:host=HOST;dbname=DBNAME;port=3306","USERNAME", "PASSWORD");
}
catch(PDOException $e){
    echo "Connection failed: " . $e->getMessage();
    exit();
}

$sql = 'INSERT INTO product_table (unique, name, type, power_unit, attr1) values (:unique, :name, :type, :power_unit, :attr1)';
$stmt = $db->prepare($sql);

foreach($products as $product){
    $params = [
        ":unique"=>$product["unique"],
        ":name"=>$product["name"],
        ":type"=>$product["type"],
        ":power_unit"=>$product["powerUnit"],
        ":attr1"=>$product["Other attribute 1"]
    ];
    var_dump($product);
    $stmt->execute($params);
}

?>
</pre>

Div单击与单选按钮相同吗? - php

有没有一种方法可以使div上的click事件与表单环境中的单选按钮相同?我只希望下面的div提交值,单选按钮很丑代码输出如下:<input id="radio-2011-06-08" value="2011-06-08" type="radio" name="radio_date&#…

AJAX调用只能与$(document).on('click')一起使用 - php

我有一个显示数据库条目的表。用户能够为每一行打开一个弹出菜单。选项之一是删除数据库条目,并且该表应通过AJAX调用相应地刷新。只要有人单击#delete-toggle中的table-popup,我就会在HTML页面上进行AJAX调用(table-popup是div,当有人单击每行中存在的表中的table-edit-button时出现的表): <div …

将输入类型复选框关联到输入类型文本 - php

我有一个问题,我需要将输入类型复选框与输入类型文本关联。情况如下:从数据库中提取数据。 PK数据是复选框的值。当复选框选择输入类型的文本时,您可以在其中输入特定数字。现在的问题是,选中所有类型的复选框输入文本都会被激活。我希望通过选择复选框输入,仅启用与复选框相关联的输入。我的HTML代码(此代码创建一个输入复选框,并为数据库中的每个记录输入文本,而我要激活…

显示基于主类别的子类别不适用于AJAX - php

我的数据库中有一个“ make”和“ model”表。当我回声汽车“制造”时,它可以正常工作。但是,我希望汽车“模型”下拉列表根据选定的“制造商”与ajax一起显示,因此在视图中不起作用但是,我需要的所有信息都显示在控制台的“网络”选项卡上。问题出在哪里?这是我的ajax代码:<script type="text/javascript…

提交表单后显示模式对话框 - php

提交下载文件后,我有一张表格。我要自动而不是自动下载文件..以显示模态对话框并显示下载链接。<form name="softwareform" id="softwareform" action="../downloadlink.php" method="POST" alig…