【问题标题】:PHP/HTML - Multiple page screen scrape, export to .txt with commas between dates and valuesPHP/HTML - 多页屏幕抓取,导出到 .txt,日期和值之间有逗号
【发布时间】:2011-05-28 16:12:42
【问题描述】:

我正在尝试抓取网页(请参阅代码)- 以及那些及时返回的页面(您可以在页面本身中看到日期“20110509”)- 以获得简单的数字字符串。我似乎无法通过反复试验(我是编程新手)弄清楚如何解析我想要的表中的特定数据。我一直在尝试使用没有 curl 或其他类似东西的简单 PHP/HTML。这可能吗?我认为我的主要问题是 使用从源代码中获取数据所需的分隔符。

我希望程序从它可以的第一页开始,例如“20050101”,并扫描每一页直到当前日期,获取特定数据,例如“最新关闭"(列)、“关闭臂”(行),并将相应日期的值导出到单个 .txt 文件中,日期与值用逗号分隔。每次运行程序时,都应将日期/值附加到现有的文本文件中。

我知道下面的许多代码行都是垃圾,这是我学习过程的一部分。

<html>
<title>HTML with PHP</title>
<body>

<?php

$rawdata = file_get_contents('http://online.wsj.com/mdc/public/page/2_3021-tradingdiary2-20110509.html?mod=mdc_pastcalendar');
//$data = substr(' ', $data);
//$begindate = '20050101';
//$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B"); 
//if (preg_match(' <td class="text"> ' , $data , $content)) {
//$content = str_replace($newlines

echo $rawdata;
///file_put_contents( 'NYSETRIN.html' , $content , FILE_APPEND);

?>

<b>some more html</b>

<?php
?>

</body>
</html>

【问题讨论】:

  • 您的意思是说您正在收集网页中的所有纯文本?
  • 不,不是所有的纯文本,只是表格中出现的某些数据。我以为我很清楚这一点,我在上面包含了我要解析的值的示例...
  • 我看到了你要解析的网址。我猜你想使用股票市场数据。不是吗?
  • 是的,我认为这很明显..
  • 您可以通过其他方式进行操作。我想我对处理股市数据有一些想法。 PM我到sujitagarwal.com@gmail.com

标签: php html parsing scrape


【解决方案1】:

好吧,让我们这样做吧。我们将首先将数据加载到 HTML 解析器中,然后从中创建一个 XPath 解析器。 XPath 将帮助我们轻松地浏览 HTML。所以:

$date = "20110509";
$data = file_get_contents("http://online.wsj.com/mdc/public/page/2_3021-tradingdiary2-{$date}.html?mod=mdc_pastcalendar");

$doc = new DOMDocument();
@$doc->loadHTML($data);

$xpath = new DOMXpath($doc);

现在我们需要获取一些数据。首先让我们获取所有数据表。看源码,这些表是用mdcTable的类表示的:

$result = $xpath->query("//table[@class='mdcTable']");
echo "Tables found: {$result->length}\n";

到目前为止:

$ php test.php
Tables found: 5

好的,我们有桌子了。现在我们需要获取特定的列。因此,让我们使用您提到的最新关闭专栏:

$result = $xpath->query("//table[@class='mdcTable']/*/td[contains(.,'Latest close')]");
foreach($result as $td) {
  echo "Column contains: {$td->nodeValue}\n";
}

目前的结果:

$ php test.php
Column contains: Latest close
Column contains: Latest close
Column contains: Latest close
... etc ...

现在我们需要列索引来获取特定行的特定列。我们通过计算所有先前的兄弟元素,然后添加一个来做到这一点。这是因为元素索引选择器是 1 索引的,而不是 0 索引的:

$result = $xpath->query("//table[@class='mdcTable']/*/td[contains(.,'Latest close')]");
$column_position = count($xpath->query('preceding::*', $result->item(0))) + 1;
echo "Position is: $column_position\n";

结果是:

$ php test.php
Position is: 2

现在我们需要获取我们的特定行:

$data_row = $xpath->query("//table[@class='mdcTable']/*/td[starts-with(.,'Closing Arms')]");
echo "Returned {$data_row->length} row(s)\n";

这里我们使用starts-with,因为行标签中有一个 utf-8 符号。这使它更容易。到目前为止的结果:

$ php test.php
Returned 4 row(s)

现在我们需要使用列索引来获取我们想要的数据:

$data_row = $xpath->query("//table[@class='mdcTable']/*/td[starts-with(.,'Closing Arms')]/../*[$column_position]");
foreach($data_row as $row) {
  echo "{$date},{$row->nodeValue}\n";
}

结果是:

$ php test.php
20110509,1.26
20110509,1.40
20110509,0.32
20110509,1.01

现在可以将其写入文件。现在,我们没有这些适用的市场,所以让我们继续抓住那些:

$headings = array();
$market_headings = $xpath->query("//table[@class='mdcTable']/*/td[@class='colhead'][1]");
foreach($market_headings as $market_heading) {
  $headings[] = $market_heading->nodeValue;
}

现在我们可以使用计数器来参考我们所处的市场:

$data_row = $xpath->query("//table[@class='mdcTable']/*/td[starts-with(.,'Closing Arms')]/../*[$column_position]");
$i = 0;
foreach($data_row as $row) {
  echo "{$date},{$headings[$i]},{$row->nodeValue}\n";
  $i++;
}

输出是:

$ php test.php
20110509,NYSE,1.26
20110509,Nasdaq,1.40
20110509,NYSE Amex,0.32
20110509,NYSE Arca,1.01

现在由你来做:

  • 这可以做成一个带日期的函数
  • 您需要代码来写出文件。查看filesystem functions 获取提示
  • 这可以扩展为使用不同的列和不同的行

【讨论】:

  • 感谢这个例子,它真的很有帮助
  • @Adam 我真的推荐阅读 XPath,它是一个非常强大的 HTML 解析工具 (w3.org/TR/xpath)。然后我建议查看 PHP 中所有可用的 DOM 函数:(us.php.net/manual/en/book.dom.php)
  • 是的,我已经计划好了,感谢您的链接和帮助。我仍在尝试理解基本的 php 代码,以及操纵您编写的内容以按照我想要的方式获得输出。我唯一想做的事情是沿着类似的路线。我已经打开了关于 DOM 函数的第二个链接,因为这是我一直用来了解如何使用函数的链接。
【解决方案2】:

我建议使用HTML Agility Pack,它是一个 HTML 解析器,对于在 HTML 文档中查找特定内容非常方便。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多