2013-08-05 2 views
0

PHP Simple HTML DOM을 사용하여 다음 HTML로 웹 페이지를 구문 분석합니다. 각 <li>에 여분의 </span> 태그가 있음을 확인하십시오.PHP 간단한 HTML DOM 파서가 잘못된 데이터를 나타냄

<li> 
    <span class="name"> 
    <a href="">Link</a> asdasd 
    </span> 
    </span> 
</li> 
<li> 
    <span class="name"> 
    <a href="">Link</a> asdasd2 
    </span> 
    </span> 
</li> 

내 쿼리는 다음과 같습니다

$lis = $dom->find('li'); 
foreach ($lis as $li) { 
    $spans = $li->find('span'); 
    foreach ($spans as $span) { 
    echo $span->plaintext."<br>"; 
    } 
} 

내 출력은 다음과 같습니다

Link asdasd 
Link asdasd2 
----------- 
Link asdasd2 
----------- 

당신이 find('span') 첫 번째 <li>에 아이들과 같이 두 개의 스팬을 찾아서로부터 값을 얻는 볼 수 있듯이 다음 <span>은 찾을 수 있습니다 (다음 <li>의 자식 임에도 불구하고). 후행 </span>을 제거하면 문제가 해결됩니다.

내 질문 있습니다

  1. 왜 이런 일이?

  2. 이 특별한 경우를 어떻게 해결할 수 있습니까? 다른 모든 것은 잘 돌아가며 스크립트에 큰 변화를 줄 수있는 위치에 있지 않습니다. 필요한 경우 DOM 쿼리를 쉽게 변경할 수 있습니다.

나는 시작을 계산하고 태그를 폐쇄하고 너무 많이가있는 경우 하나의 </span>을 제거에 대해 생각하고있다. 그들은 항상 <span> s이 될 것이므로, regexp로 그것을 확인하는 현명한 방법이 있습니까?

$e->getElementById(x); 
$e->getElementsById(x); 
$e->getElementByTagName(x); and 
$e->getElementsByTagName(x); 

를 첫 번째 호출에서이 마지막 호출의 사용한다 :

+1

1. 쓰레기 입력, 쓰레기 출력. 당신이 사용하는 수업은 주장만큼 견고하지 못합니다. 2.이 경우 HTML을 수정하십시오. 좀 더 일반적인 경우에는보다 견고한 HTML 파서를 사용하십시오. [DOMDocument] (http://php.net/manual/en/class.domdocument.php) –

+0

DOMDocument에서이 작업을 시작했는데, 결국 문자열 길이를 비교해야하는 오류가 발생하여 데이터를 일반 텍스트로 가져올 수 없었습니다. 노드 데이터에는 많은 쓰레기와 태그가 포함되어 있습니다. 이것은 훨씬 쉬워 보였다. 입력 HTML을 변경할 수 없습니다. – Mattis

답변

1

1) 어딘가에 <span>를 추가하여 추가 </span>를 해결하기 위해 노력하고있다. 이제는 거기에 없어야 할 여분의 기간이 있습니다. 기록을 위해, DomDocument는 아마 더 예측 가능한 방법으로, 동일한 일을 할 것입니다.

2) 단순화 :

foreach ($dom->find('li > span') as $span) { 
    echo $span->plaintext."<br>"; 
} 
//  Link asdasd <br>  Link asdasd2 <br> 

지금 당신은 당신은 단지 li의 자식 인 span를 원하는 그것을 말 했어요. 더 좋은 점은 다음과 같습니다.

foreach ($dom->find('span.name') as $span) { 
    echo $span->plaintext."<br>"; 
} 

이러한 속성을 사용하면 효과적입니다.

+0

여기에 쓴 문제는 상당히 단순화되어 더 읽기 쉽습니다. 나는 일반 텍스트 데이터와 li : s의 다른 것들도 필요로했다. 그러나, 나는 $ f-> parent()로 팁을 사용하고 속임수로 모든 것을 해결했다. 감사! – Mattis

1
$newTxt = preg_replace('/\<\/span\>[\S]*\<\/span\>/','</span>',$txt); 

방법 '발견은 (X)는'의 등가물을 반환 할 수 있습니다 오버로드 기능입니다. 세 번째 가능성의 두 번째 $ li. 이것은 아마도 당신이 API에 따라 묻고있는 질문의 최적화 방법 일 것입니다. 나는 당신이 두 경우 모두에서 세 번째 전화의 사용을 요구했기 때문에 당신의 API의 버그를 발견 한 것 같아요 : 간단한

$e->getElementByTagName(); 
+0

감사! 나는 당신의 영어를 이해했다고 생각한다. – Mattis

+0

그래, 나는 당신이 묘사 한 상황이 확실히 단순화 되었기 때문에 정규 표현식을 나의 기여에서 가장 중요한 부분으로 생각했다. (클래스 = '이름'및 링크). 내가 만든 침묵의 제안은 Simple HTML DOM으로 일을하지 못한다면 기본적인 방법이 좋은 대안이라는 것입니다. 나는 그들이하는 말을 전달하지 않는 도구에 대해 많은 인내심을 갖지 않습니다. 예측할 수 없게 만듭니다. 장기적으로 잘못된 HTML을 제거하는 최선의 해결책이 있습니다. 항상 가능한 것은 아니므로, 당신이 비 관입 솔루션을 찾은 것을 기쁘게 생각합니다. –

관련 문제