简单 Html Dom 抓取一半页面
Simple Html Dom Scraping half the page
我正在尝试使用简单的-html-dom 来抓取这个 url https://nrg91.gr/nrg-airplay-chart/,但它似乎没有得到完整的 html源代码。此代码:
include_once('simple_html_dom.php');
$html = file_get_html('https://nrg91.gr/nrg-airplay-chart');
echo $html->plaintext;
显示 h1 之前的内容,就在我要查找的内容之前。从简单的-html-dom 手动示例,这应该显示来自 url:
的所有链接
foreach($html->find('a') as $e)
echo $e->href . '<br>';
但它只显示到主导航菜单的链接,而不是来自主体或页脚的链接。
我也尝试使用 prerender.com 来完全加载 url,然后再将其传递给 file_get_html,但结果是一样的。我究竟做错了什么?
那个图书馆好像7年没更新了。我总是建议使用 PHP's built-in functions:
$url = "https://nrg91.gr/nrg-airplay-chart/";
$dom = new DomDocument();
libxml_use_internal_errors(true);
$dom->load($url);
foreach($dom->getElementsByTagName("a") as $e) {
echo $e->getAttribute("href") . "\n";
}
这是我使用 DOMDocument 和 SimpleXML 获取 rank/artist/title/youtube 数据的超级肮脏方法。
概念是通过 xpath //ul[@id="chart_ul"]/li
定位每个 "row" 数据,然后使用 dom_import_simplexml( $outer )->getNodePath()
为 select 各个元素构建一个新的 xpath可以找到所需的数据。
$temp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'nrg-airplay-chart.html';
if( file_exists( $temp ) === false or filemtime( $temp ) < time() - 3600 )
{
file_put_contents( $temp, $html = file_get_contents('https://nrg91.gr/nrg-airplay-chart/') );
}
else
{
$html = file_get_contents( $temp );
}
$dom = new DOMDocument();
$dom->loadHTML( $html );
$xml = simplexml_import_dom( $dom );
$array = array();
foreach( $xml->xpath('//ul[@id="chart_ul"]/li') as $index => $set )
{
$basexpath = dom_import_simplexml( $set )->getNodePath();
$array[] = array(
'ranking' => (string) $xml->xpath( $basexpath . '//span[@id="ranking"]' )[0],
'artist' => (string) $xml->xpath( $basexpath . '//p[@id="artist"]/b' )[0],
'title' => (string) $xml->xpath( $basexpath . '//p[@id="title"]' )[0],
'youtube' => (string) $xml->xpath( $basexpath . '//div[@id="media"]/a/@href' )[0],
);
}
print_r( $array );
您可能想要遵守的另一种方法:
<?php
function get_content($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
$htmlContent = curl_exec($ch);
curl_close($ch);
return $htmlContent;
}
$link = "https://nrg91.gr/nrg-airplay-chart/";
$xml = get_content($link);
$dom = @DOMDocument::loadHTML($xml);
$xpath = new DOMXPath($dom);
foreach($xpath->query('//li[contains(@id,"wprs_chart-")]') as $items){
$artist = $xpath->query('.//p[@id="artist"]/b',$items)->item(0)->nodeValue;
$title = $xpath->query('.//p[@id="title"]',$items)->item(0)->nodeValue;
echo "{$artist} -- {$title}<br>";
}
?>
你应该得到这样的输出:
PORTOGAL THE MAN -- Feel It Still
JAX JONEW Feat INA WROLDSEN -- Breathe
CAMILA CABELLO -- Havana
CARBI B, J BALVIN & BAD BUNNY -- I Like It
ZAYN Feat SIA -- Dusk Till Dawn
我正在尝试使用简单的-html-dom 来抓取这个 url https://nrg91.gr/nrg-airplay-chart/,但它似乎没有得到完整的 html源代码。此代码:
include_once('simple_html_dom.php');
$html = file_get_html('https://nrg91.gr/nrg-airplay-chart');
echo $html->plaintext;
显示 h1 之前的内容,就在我要查找的内容之前。从简单的-html-dom 手动示例,这应该显示来自 url:
的所有链接 foreach($html->find('a') as $e)
echo $e->href . '<br>';
但它只显示到主导航菜单的链接,而不是来自主体或页脚的链接。
我也尝试使用 prerender.com 来完全加载 url,然后再将其传递给 file_get_html,但结果是一样的。我究竟做错了什么?
那个图书馆好像7年没更新了。我总是建议使用 PHP's built-in functions:
$url = "https://nrg91.gr/nrg-airplay-chart/";
$dom = new DomDocument();
libxml_use_internal_errors(true);
$dom->load($url);
foreach($dom->getElementsByTagName("a") as $e) {
echo $e->getAttribute("href") . "\n";
}
这是我使用 DOMDocument 和 SimpleXML 获取 rank/artist/title/youtube 数据的超级肮脏方法。
概念是通过 xpath //ul[@id="chart_ul"]/li
定位每个 "row" 数据,然后使用 dom_import_simplexml( $outer )->getNodePath()
为 select 各个元素构建一个新的 xpath可以找到所需的数据。
$temp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'nrg-airplay-chart.html';
if( file_exists( $temp ) === false or filemtime( $temp ) < time() - 3600 )
{
file_put_contents( $temp, $html = file_get_contents('https://nrg91.gr/nrg-airplay-chart/') );
}
else
{
$html = file_get_contents( $temp );
}
$dom = new DOMDocument();
$dom->loadHTML( $html );
$xml = simplexml_import_dom( $dom );
$array = array();
foreach( $xml->xpath('//ul[@id="chart_ul"]/li') as $index => $set )
{
$basexpath = dom_import_simplexml( $set )->getNodePath();
$array[] = array(
'ranking' => (string) $xml->xpath( $basexpath . '//span[@id="ranking"]' )[0],
'artist' => (string) $xml->xpath( $basexpath . '//p[@id="artist"]/b' )[0],
'title' => (string) $xml->xpath( $basexpath . '//p[@id="title"]' )[0],
'youtube' => (string) $xml->xpath( $basexpath . '//div[@id="media"]/a/@href' )[0],
);
}
print_r( $array );
您可能想要遵守的另一种方法:
<?php
function get_content($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
$htmlContent = curl_exec($ch);
curl_close($ch);
return $htmlContent;
}
$link = "https://nrg91.gr/nrg-airplay-chart/";
$xml = get_content($link);
$dom = @DOMDocument::loadHTML($xml);
$xpath = new DOMXPath($dom);
foreach($xpath->query('//li[contains(@id,"wprs_chart-")]') as $items){
$artist = $xpath->query('.//p[@id="artist"]/b',$items)->item(0)->nodeValue;
$title = $xpath->query('.//p[@id="title"]',$items)->item(0)->nodeValue;
echo "{$artist} -- {$title}<br>";
}
?>
你应该得到这样的输出:
PORTOGAL THE MAN -- Feel It Still
JAX JONEW Feat INA WROLDSEN -- Breathe
CAMILA CABELLO -- Havana
CARBI B, J BALVIN & BAD BUNNY -- I Like It
ZAYN Feat SIA -- Dusk Till Dawn