আমি পিএইচপি ডম ব্যবহার করছি এবং আমি একটি ডোম নোডের মধ্যে একটি নির্দিষ্ট শ্রেণীর নাম রয়েছে এমন একটি উপাদান পাওয়ার চেষ্টা করছি। সেই উপ-উপাদানটি পাওয়ার সবচেয়ে ভাল উপায় কী?
আপডেট: আমি ব্যবহার শেষMechanize
পিএইচপি যা দিয়ে কাজ করা অনেক সহজ ছিল।
আমি পিএইচপি ডম ব্যবহার করছি এবং আমি একটি ডোম নোডের মধ্যে একটি নির্দিষ্ট শ্রেণীর নাম রয়েছে এমন একটি উপাদান পাওয়ার চেষ্টা করছি। সেই উপ-উপাদানটি পাওয়ার সবচেয়ে ভাল উপায় কী?
আপডেট: আমি ব্যবহার শেষMechanize
পিএইচপি যা দিয়ে কাজ করা অনেক সহজ ছিল।
উত্তর:
আপডেট: *[@class~='my-class']
সিএসএস নির্বাচকের এক্সপাথ সংস্করণ
হ্যাকারের মন্তব্যের জবাবে নীচে আমার মন্তব্যের পরে, আমি কৌতূহলী হয়ে উঠি এবং পিছনের কোডটি সন্ধান করি Zend_Dom_Query
। দেখে মনে হচ্ছে উপরের নির্বাচকটি নিম্নলিখিত xpath (অনির্ধারিত) তে সংকলিত হয়েছে:
[contains(concat(' ', normalize-space(@class), ' '), ' my-class ')]
সুতরাং পিএইচপি হবে:
$dom = new DomDocument();
$dom->load($filePath);
$finder = new DomXPath($dom);
$classname="my-class";
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
মূলত, আমরা এখানে যা করি তার সবগুলিই class
বৈশিষ্ট্যটিকে সাধারণীকরণ করা হয় যাতে একটি একক শ্রেণিও ফাঁকা জায়গাগুলির সাথে আবদ্ধ থাকে এবং সম্পূর্ণ শ্রেণীর তালিকা ফাঁকা জায়গায় আবদ্ধ থাকে। তারপরে ক্লাসটি যুক্ত করুন যা আমরা একটি স্থান দিয়ে সন্ধান করছি। এইভাবে আমরা কার্যকরভাবে অনুসন্ধান করছি এবং কেবলমাত্র উদাহরণগুলি খুঁজে পাচ্ছি my-class
।
একটি এক্সপ্যাথ নির্বাচনকারী ব্যবহার করবেন?
$dom = new DomDocument();
$dom->load($filePath);
$finder = new DomXPath($dom);
$classname="my-class";
$nodes = $finder->query("//*[contains(@class, '$classname')]");
যদি এটি কেবলমাত্র এক ধরণের উপাদান থাকে তবে আপনি *
নির্দিষ্ট ট্যাগের সাথে এটি প্রতিস্থাপন করতে পারেন ।
আপনার যদি খুব জটিল সিলেক্টর এর সাথে প্রচুর পরিমাণে করার দরকার হয় তবে আমি সুপারিশ করব Zend_Dom_Query
যা সিএসএস নির্বাচক সিনট্যাক্স (একটি লা জিকুয়েরি) সমর্থন করে:
$finder = new Zend_Dom_Query($html);
$classname = 'my-class';
$nodes = $finder->query("*[class~=\"$classname\"]");
my-class2
, তবে বেশ মিষ্টি। সমস্ত উপাদানগুলির মধ্যে প্রথমটি বেছে নেওয়ার কোনও উপায়?
class
উদাহরণস্বরূপ একাধিক শ্রেণী থাকতে পারে: <a class="my-link link-button nav-item">
।
//*[contains(concat(' ', normalize-space(@class), ' '), ' classname ')]
(খুব তথ্যপূর্ণ: সিএসএস নির্বাচক এবং এক্সপাথ এক্সপ্রেশন )।
contains
সাথে সম্মিলিতভাবে ব্যবহার করা দরকার concat
... আমরা শ্রেণীর উভয় পাশের ফাঁকা জায়গাগুলির প্যাডিংয়ের বিবরণ আলোচনা করছি যা আপনি কেবল একপাশে সন্ধান করছেন বা কেবল প্যাডিং করছেন। হয় যদিও কাজ করা উচিত।
আপনি যদি জেন্ড ছাড়া ক্লাসের অন্তর্নির্মিত HTML পেতে চান তবে আপনি এটি ব্যবহার করতে পারেন:
$dom = new DomDocument();
$dom->load($filePath);
$classname = 'main-article';
$finder = new DomXPath($dom);
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
$tmp_dom = new DOMDocument();
foreach ($nodes as $node)
{
$tmp_dom->appendChild($tmp_dom->importNode($node,true));
}
$innerHTML.=trim($tmp_dom->saveHTML());
echo $innerHTML;
$classname = 'main-article'
আমি মনে করি গৃহীত উপায়টি আরও ভাল তবে আমি অনুমান করি এটি সম্ভবত কার্যকর হবে
function getElementByClass(&$parentNode, $tagName, $className, $offset = 0) {
$response = false;
$childNodeList = $parentNode->getElementsByTagName($tagName);
$tagCount = 0;
for ($i = 0; $i < $childNodeList->length; $i++) {
$temp = $childNodeList->item($i);
if (stripos($temp->getAttribute('class'), $className) !== false) {
if ($tagCount == $offset) {
$response = $temp;
break;
}
$tagCount++;
}
}
return $response;
}
$classResult = getElementByClass($dom, 'div', 'm-signature-pad'); $classResult->nodeValue = ''; $enode = $dom->createElement('img'); $enode->setAttribute('src', $signatureImage); $classResult->appendChild($enode);
DomXPath
বা ব্যবহার না করে অন্য পদ্ধতিও রয়েছেZend_Dom_Query
।
ডেভের মূল ফাংশনের উপর ভিত্তি করে, আমি নিম্নলিখিত ফাংশনটি লিখেছি যা প্যারেন্ট নোডের সমস্ত সন্তানকে ফিরিয়ে দেয় যাদের ট্যাগ এবং শ্রেণি প্যারামিটারগুলির সাথে মেলে।
function getElementsByClass(&$parentNode, $tagName, $className) {
$nodes=array();
$childNodeList = $parentNode->getElementsByTagName($tagName);
for ($i = 0; $i < $childNodeList->length; $i++) {
$temp = $childNodeList->item($i);
if (stripos($temp->getAttribute('class'), $className) !== false) {
$nodes[]=$temp;
}
}
return $nodes;
}
ধরুন আপনার $html
নীচের এইচটিএমএল একটি ভেরিয়েবল রয়েছে :
<html>
<body>
<div id="content_node">
<p class="a">I am in the content node.</p>
<p class="a">I am in the content node.</p>
<p class="a">I am in the content node.</p>
</div>
<div id="footer_node">
<p class="a">I am in the footer node.</p>
</div>
</body>
</html>
ব্যবহার getElementsByClass
যেমন সহজ:
$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadHTML($html);
$content_node=$dom->getElementById("content_node");
$div_a_class_nodes=getElementsByClass($content_node, 'div', 'a');//will contain the three nodes under "content_node".
DOMDocament টাইপ এবং phpQuery ধীর এর খারাপ মেমরি ফাঁসের সমস্যা রয়েছে। আমি ব্যবহার করে শেষ করেছি:
https://github.com/wasinger/htmlpagedom
একটি শ্রেণি নির্বাচন করতে:
include 'includes/simple_html_dom.php';
$doc = str_get_html($html);
$href = $doc->find('.lastPage')[0]->href;
আমি আশা করি এটি অন্য কাউকেও সহায়তা করে