[英]Get data from product using XPATH nodes and insert them into table
我正在嘗試從外部網站獲取產品數據並將其插入特殊表中-每個找到的節點元素都需要導入到產品表中產品的相應列中!
找到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);
}
}
}
}
}
}
我已將您的代碼並在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>
您可以做的一件簡單的事,就是在使用XPath時,可以將一個節點用作進一步搜索的上下文,因此,一旦有了產品節點列表,就可以以此為起點提取其他數據。
舉個例子...
$dom = new DomDocument();
$dom->loadXML($xml);
$xpath = new DomXPath($dom);
$products = [];
$data = $xpath->query("//div[@class='single_product']");
foreach ($data as $item) {
$name = $xpath->evaluate('string(descendant::div[@data-field="description_detail"]/h3/a/@title)'
,$item);
$imageName = $xpath->evaluate('string(descendant::div[@data-section="featured_image"]//img/@src)'
,$item);
$typePower = $xpath->evaluate('string(descendant::div[@data-field="description_detail"]/a/p/text())'
,$item);
$description = $xpath->evaluate('string(descendant::div[@data-field="description"]/a)'
,$item);
$products[$name] = array( "image" => $imageName,
"typePower" => $typePower,
"description" => $description
);
}
print_r($products);
注意evaluate()
方法的第二個參數,它是第一個query()
的節點。
我還使用了evaluate
,使我可以立即將節點作為字符串返回,而無需任何進一步的轉換(它允許我將string()
用作查詢的一部分)。
沒有后處理,因此您可能必須整理一些數據並且沒有數據庫訪問權限(您應遵循使用准備好的語句的示例),但這首先顯示了提取數據的重要部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.