我解析一个网页,并按照链接来将链接从一个页面映射到另一个页面。我只拉取链接所在页面的标题,用于链接页面的URL以及URL导向的页面标题。在这个代码块中是否会停止执行?
我的代码工作正常,可以发现我感兴趣的链接,并且可以下载子页面以查找其他产品链接。至少有一百个页面有几百个,所以它是几个解析HTML文件。我正在构建一个$products[index]
的表单,其中包含的是一个数组array(['url'] => URLToPage, ['title'] => TitleOfPage, ['link_title'] => TitleOfLinkedPage)
,正如我希望的那样。
该脚本工作正常,直到我添加此代码片段,之后脚本将停止执行没有错误,警告,通知或任何东西;它从来没有达到脚本的末尾。我已包含set_time_limit(0)
以防止执行时间过期,因为此脚本需要一些时间才能完成。如果找到任何链接,并且$ products始终是一个数组,并且在测试用例中输出了$ link_html_strings以验证页面是否按预期方式被检索,则此代码在$ products数组填充后执行。这是有问题的代码:需要
// Populate the destination link titles
if (isset($products) && count($products) > 0)
{
foreach($products as $id => $product)
{
$from_this_page = $product['url'];
if ($DEBUG) echo 'Parsing ' . $from_this_page . '.<br />';
$link_html_string = file_get_contents($from_this_page, NULL, NULL, NULL, 500);
$string_parts = explode('<title>', $link_html_string);
$string_parts = explode('</title>', $string_parts[1]);
$products[$id]['link_title'] = $string_parts[0];
if ($DEBUG) echo 'Found title: ' . $products[$id]['link_title'] . '<br />';
ob_flush();
flush();
}
}
从来就没有真正应该超过500字,但是,我读了整个文件的时候,所以我通过限制读降低负载(我认为)有内存使用的一些担忧。我想也许这个脚本已经使用了PHP分配的所有内存。包含这个时,它会遍历这个循环几次,但在某个时候停止执行,这一点也不完全相同。我将得到几个回应分析什么文件。
这是脚本的完整代码,包括回答关于评论中产品内容的问题。
<?php
// PHP HTML DOM Parser from http://simplehtmldom.sourceforge.net/
require_once('includes/simple_html_dom.php');
//error_reporting(E_ALL);
set_time_limit(0);
// Debugging flag
$DEBUG = false;
function reportProducts($category, $products)
{
echo '<table width="90%" align="center"><tr><th colspan="3">';
echo $category . ' has ' . count($products) . ' products listed, or in subpages.';
echo '</th></tr>';
echo '<tr><td bgcolor="#777777" width="30%">This page</td>
<td bgcolor="#bbbbbb" width="30%">links with</td>
<td bgcolor="#777777" width="30%">to this page</td></tr>';
foreach($products as $product)
{
echo '<tr><td bgcolor="#777777">' . $product['title'] . '</td>
<td bgcolor="#bbbbbb"><a href="' . $product['url'] . '">' . $product['url'] .
'</a></td><td bgcolor="#777777">' . $product['link_title'] . '</td></tr>';
}
echo '</table><br />';
ob_flush(); // Server may buffer again, preventing incremental display
flush();
}
function parseProductsForPage($page_to_parse)
{
global $DEBUG;
$failed = false;
$product_id = 0;
$page_dom = new simple_html_dom();
$page_html_string = @file_get_contents($page_to_parse->href);
$load_state = @$page_dom->load($page_html_string);
if ($load_state === NULL)
{
// Find any direct product pages for this page
if ($DEBUG) echo $page_to_parse->href . ' being checked for products... ';
$possible = $page_dom->find('a[onclick]');
foreach($possible as $link)
{
if ($link->innertext == "[ Add to cart ]")
{
$products[$product_id]['url'] = $link->href;
$titles = $page_dom->find('title');
$products[$product_id]['title'] = $titles[0]->innertext;
$product_id++;
}
}
if ($DEBUG)
{
if (isset($products))
{
echo count($products) . ' found on page.<br />';
} else
{
echo '0 found on page.<br />';
}
}
// Find subpages...
if ($DEBUG) echo $page_to_parse->href . ' being checked for links... ';
$subpages = $page_dom->find('a[class=buy]');
if ($DEBUG) echo count($subpages) . ' found.<br />';
// ... and parse
foreach($subpages as $subpage)
{
$subpage_dom = new simple_html_dom();
$subpage_html_string = @file_get_contents($subpage->href);
$load_state = @$subpage_dom->load($subpage_html_string);
if ($load_state === NULL)
{
// Find any direct product pages for this page
if ($DEBUG) echo $subpage->href . ' being checked for products... ';
$possible = $subpage_dom->find('a[onclick]');
foreach($possible as $link)
{
if ($link->innertext == "[ Add to cart ]")
{
$products[$product_id]['url'] = $link->href;
$titles = $page_dom->find('title');
$products[$product_id]['title'] = $titles[0]->innertext;
$product_id++;
}
}
if ($DEBUG)
{
if (isset($products))
{
echo count($products) . ' found on page.<br />';
} else
{
echo '0 found on page.<br />';
}
}
$subpage_dom->clear();
} else
{
$failed[] = $subpage->href;
}
$subpage_dom->clear();
unset($subpage_dom);
}
// Populate the destination link titles
if (isset($products) && count($products) > 0)
{
foreach($products as $id => $product)
{
// $from_this_page = $product['url'];
// if ($DEBUG) echo 'Parsing ' . $from_this_page . '.<br />';
// $link_html_string = file_get_contents($from_this_page, NULL, NULL, NULL, 500);
// $string_parts = explode('<title>', $link_html_string);
// $string_parts = explode('</title>', $string_parts[1]);
// $products[$id]['link_title'] = $string_parts[0];
// if ($DEBUG) echo 'Found title: ' . $products[$id]['link_title'] . '<br />';
// ob_flush();
// flush();
}
}
} else
{
$failed[] = $page_to_parse->href;
}
$titles = $page_dom->find('title');
if (isset($products)) reportProducts($titles[0]->innertext, $products);
$page_dom->clear();
unset($page_dom);
return $failed;
}
// Initialize the object
$html = new simple_html_dom();
$html->load_file('index.html');
// Start output buffer
ob_start();
// Find all product categories listed on the website
if ($DEBUG) echo '<h1>Collecting links from LHN...</h1>';
$sidelinks = $html->find('a[class=sidelink_main]');
$html->clear();
unset($html);
echo '<h1>Found ' . count($sidelinks) . ' categories.</h1><br />';
ob_flush(); // Server may buffer output, preventing incremental display
flush();
// Find links and products for each category
foreach($sidelinks as $sidelink)
{
if ($DEBUG) echo 'Sending ' . $sidelink->href . ' to parser.<br />';
$parse_failed = parseProductsForPage($sidelink);
if ($parse_failed)
{
foreach($parse_failed as $failure)
{
$failures[] = $failure;
}
}
}
echo count($failures) . ' pages failed to parse.<br />';
echo '<br />FIN!<br />'; // Easily searched to verfiy end of script was reached, also
// celebratory.
ob_end_flush(); // Clear output buffer
flush();
?>
我把它'$ DEBUG'有一个真正的样的价值?假设情况如此,无论什么问题显然必须发生在第一次通过循环的条件“echo”语句之前。 – Hammerite
也是一个无关紧要的问题,我敢肯定'&& count($ products)> 0'位是不必要的,因为如果数组为空,那么'foreach'循环只会循环零次。 – Hammerite
@Hammerite我是否错误地认为条件语句'if($ DEBUG)echo ...;'不仅影响该行?和in一样,尽管'DEBUG'(这是真/假)的值'$ link_html_string = file_get_contents(...);'会被执行? – ToothlessRebel