0

私は「Simple HTML Dom」を使用して HN フロント ページ (news.ycombinator.com) をスクレイピングしていますが、これはほとんどの場合うまく機能します。

ただし、スクレイパーが探している要素 (スコア、ユーザー名、コメント数など) が欠けている仕事や会社を宣伝することがあります。

恥知らずなプロモーション

もちろん、これは配列を壊し、スクリプトの出力を壊します:

 <?php

// 2012-02-12 Maximilian (Extract news.ycombinator.com's Front Page)

// Set the header during development
//header ("content-type: text/xml");

// Call the external PHP Simple HTML DOM Parser (http://simplehtmldom.sourceforge.net/manual.htm)
include('lib/simple_html_dom.php');

date_default_timezone_set('Europe/Berlin');

// Download 'news.ycombinator.com' content
//$tmp = file_get_contents('http://news.ycombinator.com');
//file_put_contents('get.tmp', $tmp);

// Retrieve the content
$html = file_get_html('tc.tmp');

// Set the extraction pattern for each item
$title = $html->find("tr td table tr td.title a");
$score = $html->find("tr td.subtext span");
$user = $html->find("tr td.subtext a[href^=user]");
$link = $html->find("tr td table tr td.title a");
$time = $html->find("tr td.subtext");
$additionals = $html->find("tr td.subtext a[href^=item?id]");

// Construct the feed by looping through the items
for($i=0;$i<29;$i++) {

$cr=1;

// Check if the item points to an external website
if (!strstr($link[$i]->href,'http')) {

$url = 'http://news.ycombinator.com/'.$link[$i]->href;
$description = "Join the discussion on Hacker News.";


} else {

$url = $link[$i]->href;

// Getting content here

if (empty($abstract)) {

$description ="Failed to load any relevant content. Please try again later.";

} else {

$description = $abstract;

}

}
// Put all the items together
  $result .= '<item><id>f'.$i.'</id><title>'.htmlspecialchars(trim($title[$i]->plaintext)).'</title><description><![CDATA['.$description.']]></description><pubDate>'.str_replace('  | '.$additionals[$i]->plaintext,'',str_replace($score[$i]->plaintext.' by '.$user[$i]->plaintext.' ','',$time[$i]->plaintext)).'</pubDate><score>'.$score[$i]->plaintext.'</score><user>'.$user[$i]->plaintext.'</user><comments>'.$additionals[$i]->plaintext.'</comments><id>'.substr($additionals[$i]->href,8).'</id><discussion>http://news.ycombinator.com/'.$additionals[$i]->href.'</discussion><link>'.htmlspecialchars($url).'</link></item>'; 
}

$output = '<rss><channel><id>news.ycombinator.com Frontpage</id><buildDate>'.date('Y-m-d H:i:s').'</buildDate>'.$result.'</channel></rss>';

file_put_contents('tc.xml', $output);


?>

正しい出力の例を次に示します

<item>
<id>f0</id>
<title>Show HN: Bootswatch, free swatches for your Bootstrap site</title>
<description><![CDATA[Easy to Install Simply download the CSS file from the swatch of your choice and replace the one in Bootstrap. No messing around with hex values. Whole New Feel We've all been there with the black bar and blue buttons. See how a splash of color and typography can transform the feel of your site. Modular Changes are contained in just two LESS files, enabling modification and ensuring forward compatibility.]]></description>
<pubDate>3 hours ago</pubDate>
<score>196 points</score>
<user>parkov</user>
<comments>30 comments</comments>
<id>3594540</id>
<discussion>http://news.ycombinator.com/item?id=3594540</discussion>
<link>http://bootswatch.com</link>
</item>
<item>
<id>f1</id>
<title>Louis CK inspires Jim Gaffigan to sell comedy special for $5 online</title>
<description><![CDATA[Dear Internet Friends,Inspired by the brilliant Louis CK, I have decided to debut my all-new hour stand-up special on my website, Jimgaffigan.com.Beginning sometime in April, “Jim Gaffigan: Mr. Universe” will be available exclusively for download for only $5. A dollar from each download will go directly to The Bob Woodruff Foundation; a charity dedicated to serving injured Veterans and their families.I am confident that the low price of my new comedy special and the fact that 20% of each $5 download will be donated to this very noble cause will prevent people from stealing it. Maybe I’m being naïve, but I trust you guys.]]></description>
<pubDate>57 minutes ago</pubDate>
<score>25 points</score>
<user>rkudeshi</user>
<comments>4 comments</comments>
<id>3595285</id>
<discussion>http://news.ycombinator.com/item?id=3595285</discussion>
<link>http://www.whosay.com/jimgaffigan/content/218011</link>
</item>

そして、これは間違った出力の例です。要素が空ではないことに注意してください。したがって、エラーをキャッチして次の項目にジャンプすることはできません。プロモーション投稿以降はすべて壊れます。

<item>
<id>f14</id>
<title>Build the next Legos: We're hiring an iOS Developer &amp; Web Developer (YC S11)</title>
<description><![CDATA[Interested in building the next generation of toys on digital devices such as the iPad? That’s what we’re doing here at Launchpad Toys with apps like Toontastic (Named one of the “Top 10 iPad Apps of 2011” by the New York Times and was recently added to the iTunes Hall of Fame) and an awesom]]><![CDATA[e suite of others we have under development. We’re looking for creative and playful coders that have made games or highly visual apps/sites in the past for our two open development positions. As a kid, you probably played with Legos endlessly and grew up to be a hacker because you still love building things. Sounds like you? Email us at howdy@launchpadtoys.com with a couple links to some projects and code that we can look at along with your resume.]]></description>
<pubDate>2 hours ago</pubDate>
<score>14 points</score>
<user>bproper</user>
<comments>7 comments</comments>
<id>3594944</id>
<discussion>http://news.ycombinator.com/item?id=3594944</discussion>
<link>http://launchpadtoys.com/blog/2012/02/iosdeveloper-webdeveloper/</link>
</item>
<item>
<id>f15</id>
<title>SOPA foe Fred Wilson supports a blacklist on pirate sites</title>
<description><![CDATA[VC Fred Wilson says Google, Bing, Facebook, and Twitter should warn people when they try to log in at known pirate sites: "We don't need legislation." Fred Wilson says: If they try to pass antipiracy legislation, it will once again be 'war.' (Credit: Greg Sandoval/CNET) Fred Wilson, a well-known ven]]><![CDATA[ture capitalist from New York, says he's in favor of creating a blacklist for Web sites found to traffic in pirated films, music, and other intellectual property. The co-founder of Union Square Ventures told a gathering of media executives at the Paley Center for Media yesterday that he believes a good antipiracy measure would be for Google, Twitter, Facebook, and other major sites to issue warnings to people when they try to connect with a known pirate site. Fred Wilson, a co-founder of Union Square Ventures, says 'Our children have been taught to steal.' (Credit: Union Square Ventures) Wilson favors establishing an independent group to create a "black and white list." "The blacklist are those sites we all know are bad news," he told the audience in New York.]]></description>
<pubDate>14 points by bproper 2 hours ago  | 7 comments</pubDate>
<score>24 points</score>
<user>andrewcross</user>
<comments>12 comments</comments>
<id>3594558</id>
<discussion>http://news.ycombinator.com/item?id=3594558</discussion>
<link>http://news.cnet.com/8301-31001_3-57377862-261/post-sopa-influential-tech-investor-favors-blacklisting-pirate-sites/</link>
</item>

では、私の質問は次のとおりです。特定の要素が見つからず、find() がエラーをスローしない状況をどのように処理できますか? ゼロから始める必要がありますか、それとも HN のフロント ページをスクレイピングするためのより良い方法はありますか?

興味のある方のために、ここに XML ファイル全体を示します: http://thequeue.org/api/tc.xml

4

2 に答える 2

1

それを処理するには、チャンクごとに作業する必要があります。それを支援できるダミーのスペーサー要素があるようです:

$news = preg_split('/<tr style="height:5px"><\/tr>/',$html->find('tbody',2)->innertext);

次に、サブセレクターを使用します。

foreach($news as $article){
    $article = str_get_html($article)
    // No upvote arrow found so its not a valid article
    if(count($article->find('img')) === 0){
        continue;
    }
}

他の要素については、同じセレクターを使用します

于 2012-02-17T07:31:46.280 に答える
0

Ivan の考えのおかげで、最初にスクレイピングした HTML を配列に分割し、各ノードが投稿を表すようにしています。次に、ループ内のすべての投稿を調べて、上向きの矢印の画像が存在するかどうかを確認します。そうでない場合は、結果に追加しません。最終的にはすべてがつなぎ合わされ、スポンサー付きの投稿は除外されます。コードは次のとおりです。

$array = explode('<tr style="height:5px"></tr>',$html);
foreach ($array as $post) {

    if (!strstr($post,'grayarrow.gif')){}else{

    $clean .=  $post;

    }

}
unset($array);
$html = str_get_html($clean.'</body></html>');
于 2012-02-17T21:19:05.507 に答える