2012-12-28 4 views
4

WWW::MechanizeMojo::DOM을 사용하여 이전 vBulletin 포럼에서 텍스트를 추출하려고합니다.Mojo :: DOM을 사용하는 동안 하위 요소를 찾아내는 데 문제가 발생했습니다.

vBulletin은 의미 론적 마크 업을 위해 HTML과 CSS를 사용하지 않으며 특정 요소를 얻기 위해 Mojo::DOM->children을 사용하는 데 문제가 있습니다.

이러한 vBulletin 게시물은 내용에 따라 다르게 구성됩니다.

단일 메시지 : 스포일러와 다른 사용자의 말을 인용

<div id="postid_12345"> 
    <div class="spoiler">Yoda is Luke's father!</div> 
</div> 

단일 메시지 : 스포일러와

<div id="postid_12345"> 
    <div> 
    <table> 
     <tr> 
      <td> 
      <div>Quote originally posted by Bob</div> 
      <div>Everyone knows the sky is blue.</div> 
      </td> 
     </tr> 
    </table> 
    </div> 

I disagree with you, Bob. It's obviously green. 
</div> 

단일 메시지 : 다른 사용자의 말을 인용

<div id="postid_12345">The quick brown fox jumps over the lazy dog.<div> 

단일 메시지

위의 HTML 및 필요한 포스트 ID를 포장 배열 가정

: $dom->at($div_id)->all_text 사용

for (@post_ids) { 
    $mech->get($full_url_of_specific_forum_post); 
    my $dom = Mojo::DOM->new($mech->content); 
    my $div_id = 'postid_' . $_; 

    say $dom->at($div_id)->children('div')->first; 
    say $dom->at($div_id)->text; 
} 

나에게 어려운 인용하고 어떤 게시물에 원래의 무엇을 말할 수있게 끊어지지 않는 선에서 모든 것을 제공합니다.

$dom->at($div_id)->text을 사용하면 모든 하위 요소를 건너 뛰므로 인용 된 텍스트와 스포일러는 선택되지 않습니다.

변형을 시도한 결과는 $dom->at($div_id)->children('div')->first이지만 HTML을 포함하여 모든 것을 제공합니다.

이상적으로 각 게시물의 모든 텍스트를 각 줄마다 가져올 수 있기를 바랍니다.

POSTID12345: 
+ Quote originally posted by Bob 
+ Everyone knows the sky is blue. 
I disagree with you, Bob. It's obviously green. 

저는 Perl에서 Mojo와 녹슨을 처음 사용했습니다. 나는이 문제를 혼자서 해결하고 싶었지만 문서를보고 몇 시간 동안 손을 떼면 내 뇌가 멍 해졌고 나는 잃어 버렸다. 나는 단지 Mojo::DOMMojo::Collections이 어떻게 작동하는지 알 수 없다.

도움이 될 것입니다.

답변

2

Mojo :: DOM 소스를 보면 기본적으로 all_text method은 DOM을 반복적으로 탐색하고 모든 텍스트를 추출합니다. 이 소스를 사용하여 DOM 함수를 걷는 것을 직접 작성하십시오. 그 재귀 함수는 하나의 문자열을 반환하는 것에 달려 있습니다. 필요한 문자열을 배열로 반환하게 할 수도 있습니다.

편집 : IRC에 대한 논의 후

는 웹 스크래핑 예 업데이트되었습니다, 당신이 당신을 안내 도움이 될 수 있습니다. http://mojolicio.us/perldoc/Mojolicious/Guides/Cookbook#Web_scraping

+0

+1 귀하의 답변은 내가 올바른 방향으로 지적 받고에 엄청난 도움이되었습니다 : 몇 번의 키 입력에 , 이것은 당신이 HTML :: 선형을 사용하는 방법입니다. 고맙습니다! –

1

flattern HTML 트리에 모듈이 있습니다 (HTML::Linear). flatterning의 HTML 트리위한 목적의 설명은, 그래서 여기에 약간 길고 지루 해당 모듈과 결합 된 xpathify 도구의 출력을 보여주는 사진이다 :

보시다시피 screenshot

, HTML 트리 노드는 단일 키/값 목록이되며, 여기서 키는 해당 노드에 대한 XPath이고 값은 노드의 텍스트 속성입니다. 지난 몇 일 동안 여기

#!/usr/bin/env perl 
use strict; 
use utf8; 
use warnings; 

use Data::Printer; 
use HTML::Linear; 

my $hl = HTML::Linear->new; 
$hl->parse_file(q(vboard.html)); 

for my $el ($hl->as_list) { 
    my $hash = $el->as_hash; 
    next unless keys %{$hash}; 
    p $hash; 
} 
관련 문제