【问题标题】:PHP Web scraping of Javascript generated contents [duplicate]Javascript生成内容的PHP Web抓取[重复]
【发布时间】:2014-01-22 09:29:29
【问题描述】:

我的项目中遇到了抓取任务。

我想从 $html 中的链接中获取数据,tr 和 td 的所有表格内容,这里我试图获取链接但它只显示 javascript: self.close()

<?php
include("simple_html_dom.php");

$html = file_get_html('http://www.areacodelocations.info/allcities.php?ac=201');

 foreach($html->find('a') as $element)
   echo $element->href . '<br>'; 


  ?>

【问题讨论】:

  • 你用什么来刮痧?请将您当前的代码添加到您的问题中,使用“代码”按钮格式化。
  • areacodelocations.info/allcities.php?ac=201'); // 查找所有图片 // 查找所有链接 foreach($html->find('a') as $element) echo $element->href . '
    '; ?>
  • 嗯...这是一个与您之前引用的站点不同的站点。我的解决方案不再适用,您的解决方案现在不起作用,因为在新页面中您需要找到 TR 元素,而不是 A 元素。在该页面中只有一个 A 元素,这就是您要恢复的内容。你检查过 HTML 源代码吗?
  • @iserni .. 那么如何获取 tr 呢??
  • @lserni:我很想回滚这个问题,以便它与您的出色答案相匹配。不过,我不想妨碍您继续提供帮助:您怎么看?

标签: php html web-scraping


【解决方案1】:

通常,这类页面会加载一堆Javascript(jQuery等),然后构建界面并从数据源中检索要显示的数据。

因此,您需要在 Firefox 或类似工具中使用 Firebug 等工具打开该页面,以查看实际执行了哪些请求。如果幸运的话,您会直接在 XHR 请求列表中找到它。在这种情况下:

http://www.govliquidation.com/json/buyer_ux/salescalendar.js

请注意,此行为可能会侵犯某些许可或使用条款。在继续之前与网站管理员/数据源/版权所有者清除这一点:检测和禁止这种抓取非常容易,而识别可能只是稍微不那么容易。

无论如何,如果您在 PHP 中发出相同的调用,您可以使用非常简单的代码直接抓取数据(前提是没有会话/身份验证问题,就像这里的情况一样):

<?php

    $url = "http://www.govliquidation.com/json/buyer_ux/salescalendar.js";

    $json = file_get_contents($url);

    $data = json_decode($json);

?>

这会产生一个数据对象,您可以通过简单的循环检查和转换为 CSV。

stdClass Object
(
    [result] => stdClass Object
        (
            [events] => Array
                (
                    [0] => stdClass Object
                        (
                            [yahoo_dur] => 11300
                            [closing_today] => 0
                            [language_code] => en
                            [mixed_id] => 9297
                            [event_id] => 9297
                            [close_meridian] => PM
                            [commercial_sale_flag] => 0
                            [close_time] => 01/06/2014
                            [award_time_unixtime] => 1389070800
                            [category] => Tires, Parts & Components
                            [open_time_unixtime] => 1388638800
                            [yahoo_date] => 20140102T000000Z
                            [open_time] => 01/02/2014
                            [event_close_time] => 2014-01-06 17:00:00
                            [display_event_id] => 9297
                            [type_code] => X3
                            [title] => Truck Drive Axles @ Killeen, TX
                            [special_flag] => 1
                            [demil_flag] => 0
                            [google_close] => 20140106
                            [event_open_time] => 2014-01-02 00:00:00
                            [google_open] => 20140102
                            [third_party_url] =>
                            [bid_package_flag] => 0
                            [is_open] => 1
                            [fda_count] => 0
                            [close_time_unixtime] => 1389045600

您检索$data-&gt;result-&gt;events,在其转换为数组形式的项目上使用fputcsv(),并且Bob 是您的叔叔。

【讨论】:

    【解决方案2】:

    在第二个站点的情况下,您有一个包含多个 TR 元素的表,并且您想要捕获每个 TR 的前两个 TD 子项。

    通过检查源代码,您会看到如下内容:

    <tr>
          <td>&nbsp;Allendale</td>
          <td>&nbsp;Eastern Time
    </td>
        </tr>
        <tr>
          <td>&nbsp;Alpine</td>
          <td>&nbsp;Eastern Time
    </td>
    

    所以你只需抓住所有的 TR

    <?php
        include("simple_html_dom.php");
    
        $html = file_get_html('http://www.areacodelocations.info/allcities.php?ac=201');
    
        $fp = fopen('output.csv', 'w');
    
        if (!$fp) die("Cannot open output CSV - permission problems maybe?");
    
        foreach($html->find('tr') as $tr) {
           $csv = array(); // Start empty. A new CSV row for each TR.
           // Now find the TD children of $tr. They will make up a row.
           foreach($tr->find('td') as $td) {
               // Get TD's innertext, but 
               $csv[] = $td->innertext;
           }
           fputcsv($fp, $csv);
        }
    
        fclose($fp);
      ?>
    

    您会注意到 CSV 文本是“脏”的。那是因为实际的文字是:

          <td>&nbsp;Alpine</td>
          <td>&nbsp;Eastern Time[CARRIAGE RETURN HERE]
              </td>
    

    所以要有“Alpine”和“Eastern Time”,你必须替换

               $csv[] = $td->innertext;
    

    类似的东西

               $csv[] = strip(
                    html_entity_decode (
                      $td->innertext,
                      ENT_COMPAT | ENT_HTML401,
                      'UTF-8'
                    )
               );
    

    查看关于字符集编码和实体处理的html_entity_decode() 的 PHP 手册页。上面的ought行得通——一个ought和50美分就能给你一杯咖啡:-)

    【讨论】:

      猜你喜欢
      • 2020-07-01
      • 1970-01-01
      • 2015-04-02
      • 2013-10-09
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多