여기서는 전적으로 xpath
을 사용하지 않습니다. 우선 화이트리스트와 블랙리스트가 있습니다. 당신이 원하는 것이 무엇인지는 분명하지 않으므로 시간이 지남에 따라 바뀔 수 있다고 가정합니다.
그러면 할 수있는 일은 먼저 문제의 모든 href
속성을 선택하고 노드를 반환하는 것입니다. 즉 XPath는이 매우 좋은거야, 그래서 XPath를 사용하자 :
if (!$links = $xpath->query('//a/@href')) {
throw new Exception('XPath query failed.');
}
이제 $links
의 일반적인 DOMNodeList
을 가지고 우리가 사람들을 선택로는 0 개 이상의 DOMAttr
요소가 포함되어 있습니다. 이것들은 이제 당신이 찾고있는 필터링을 필요로합니다.
그래서 일치시키고 싶은 기준이 있습니다. 당신은 그것이 어떻게 작동해야하는지 상세하지는 않지만 매우 구체적이지 않습니다. 긍정적 인 성냥과 부정적 성냥이 있습니다. 그러나 두 경우 모두 당신은 어떤 일이 일어나지 않아야하는지 말하지 않습니다.그래서 여기에 바로 가기를 수행
function is_valid_href($href) {
// do whatever you see fit ...
return true or false;
}
그래서 href
지금 유효한지 여부를 말하는 문제가하십시오 "href"
문자열 기준 (들)과 일치하는 경우 당신은 자신에게 하나 true
또는 false
을 반환하는 함수를 작성 해결되었습니다. 가장 좋은 점은 나중에 변경할 수 있습니다.
그래서 필요한 것은 모든 링크를 정규화 된 절대 형식으로 얻는 것입니다. 이것은 더 많은 데이터 처리를 참조 의미 : URL 정상화의 다른 유형에 대한 자세한 내용은
.
그래서 href 정규화, 기본 해상도 및 유효성 검사를 캡슐화하는 다른 함수를 만듭니다. href를 잘못 경우, 그냥 그렇지 않으면 정규화 된 HREF, null
를 반환
function normalize_href($href, $base) {
// do whatever is needed ...
return null or "href string";
}
는 검증이 혜택을 누릴 수 있도록 내 경우에는 내가 심지어 HREF Net_URL2
인스턴스를 만들의 함께이를 넣어 보자.
당연히 이것을 클로저 또는 일부 클래스로 마무리하면 더 멋진 인터페이스가됩니다. 또한 당신은뿐만 아니라 XPath 식 매개 변수하게 생각 couold :
// get all href
if (!$links = $xpath->query('//a/@href')) {
throw new Exception('XPath query failed.');
}
// set a base URL
$base = 'https://stackoverflow.com/questions/9894956/xpath-query-html-find-specific-hrefs-within-anchor-tags';
/**
* @return bool
*/
function is_valid_href($href) {
...
}
/**
* @return href
*/
function normalize_href($href, $base) {
...
}
$joblinks = array();
foreach ($links as $attr) {
$href = normalize_href($attr->nodeValue, $base);
if (is_valid_href($href)) {
$joblinks[] = $href;
}
}
// your result is in:
var_dump($joblinks);
내가 본 웹 사이트의 예를 실행했습니다, 그 결과는 다음과 같습니다
array(122) {
[0]=>
object(Net_URL2)#129 (8) {
["_options":"Net_URL2":private]=>
array(5) {
["strict"]=>
bool(true)
["use_brackets"]=>
bool(true)
["encode_keys"]=>
bool(true)
["input_separator"]=>
string(1) "&"
["output_separator"]=>
string(1) "&"
}
["_scheme":"Net_URL2":private]=>
string(4) "http"
["_userinfo":"Net_URL2":private]=>
bool(false)
["_host":"Net_URL2":private]=>
string(17) "stackexchange.com"
["_port":"Net_URL2":private]=>
bool(false)
["_path":"Net_URL2":private]=>
string(1) "/"
["_query":"Net_URL2":private]=>
bool(false)
["_fragment":"Net_URL2":private]=>
bool(false)
}
[1]=>
...
[121]=>
object(Net_URL2)#250 (8) {
["_options":"Net_URL2":private]=>
array(5) {
["strict"]=>
bool(true)
["use_brackets"]=>
bool(true)
["encode_keys"]=>
bool(true)
["input_separator"]=>
string(1) "&"
["output_separator"]=>
string(1) "&"
}
["_scheme":"Net_URL2":private]=>
string(4) "http"
["_userinfo":"Net_URL2":private]=>
bool(false)
["_host":"Net_URL2":private]=>
string(22) "blog.stackoverflow.com"
["_port":"Net_URL2":private]=>
bool(false)
["_path":"Net_URL2":private]=>
string(30) "/2009/06/attribution-required/"
["_query":"Net_URL2":private]=>
bool(false)
["_fragment":"Net_URL2":private]=>
bool(false)
}
}
이 필요한 HREF 값을 필터링하는 것입니다 전적으로 XPath 쿼리를 사용합니까? 나는 그것이 가능하다고 확신하지만, 머리가 아프다 (전형적인 XPath). 아마도'$ xpath-> query()'를 사용하여 넓은 패턴 (예 :'href = "https://some-site.vendor.com/jobs/")과 일치하는 노드리스트를 얻은 다음, 몇 줄의 PHP를 사용하여 각 노드의 href 값을 더 자세히 조사하십시오. –
XPath 1.0보다는 XPath 1.0이 확실히 불필요하게 장황하게 만듭니다 ...하지만 그것이 우리가 가지고있는 전부입니다. ['registerphpfunctions'] (http://php.net/manual/en/domxpath.registerphpfunctions.php)와의 정규식 매치를 할 수있는 함수를 만들 것입니다. – Wrikken