«Попытка получить свойство необъекта» при проверке базы данных - PHP - PullRequest
0 голосов
/ 31 декабря 2010

Привет.У меня есть сценарий php, который, как предполагается, очищает веб-сайт оптовика для получения информации о продукте и вводит эту информацию в базу данных.

Я успешно собрал всю информацию для образца продукта, и при выполнении простого эха всех $ vпеременные, все выводится на экран правильно.

Теперь, после того, как я добавлю проверку, чтобы увидеть, существуют ли категории продуктов в базе данных, и фактически вставлю информацию, я получу

[Отладка phpBB] Примечание PHP: в файле /rip.php в строке 35: Попытка получить свойство необъекта [Отладка PHP]: Примечание PHP: в файле /rip.php в строке 36: Попытка получить свойство необъекта [Отладка phpBB] Примечание PHP: в файле /rip.php в строке 38: неопределенное смещение: 3 [Отладка phpB] Примечание PHP: в файле /rip.php в строке 38: неопределенное смещение: 2 [Отладка phpBB] Примечание PHP: в файле/rip.php в строке 41: попытка получить свойство необъектной фатальной ошибки: вызов функции-члена find () для необъекта в /XXXXX/public_html/XXXXX/rip.php в строке42

Однако вся информация о продукте по-прежнему вводится в базу данных.

Предполагается, что сценарий будет перемещаться по страницам, собирая информацию, но останавливается после первого продукта.

Я использую сценарий SC Chen Simple HTML DOM (http://sourceforge.net/projects/simplehtmldom/), и базовую систему phpBB для вызовов базы данных, и вот мой источник PHP:

<?php

define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/simple_html_dom.' . $phpEx);

// Start session management
$user->session_begin();
$auth->acl($user->data);
$user->setup();

function save($in, $out)
{
    $tempDir = './rip_images';
 $finalDir = $out;
 $imageUrl = $in;

 $file = basename($imageUrl);

 exec("cd $tempDir && wget --quiet $imageUrl");

 if (rename("$tempDir/$file", "$finalDir") === false) {
  die('Failed while trying to move image file from temp dir to final dir');
 }
}

function scrape($i)
{
 $html = file_get_html('XXXXXXXXX.com/index.php?main_page=product_info&products_id='.$i.'&zenid=e4b7dde8de02e1df005d4549e2e3e529'); 

 foreach($html->find('body') as $html)
 {
  $item['title'] = trim($html->find('#productName', 0)->plaintext);
  $item['price'] = trim($html->find('#productPrices', 0)->plaintext);
  $item['cat'] = $html->find('#navBreadCrumb', 0)->plaintext;
  list($home, $item['cat'], $item['subcat'], $title) = explode("::", $item['cat']);
  $item['cat'] = str_replace("&nbsp;", "", $item['cat']);
  $item['subcat'] = str_replace("\n", "", str_replace("&nbsp;", "", $item['subcat']));
  $item['desc'] = trim($html->find('#productDescription', 0)->plaintext);
  $item['model'] = $html->find('ul#productDetailsList', 0)->find('li', 0)->plaintext;
  $item['model'] = explode(":", $item['model']);
  $item['model'] = trim($item['model'][1]);
  $item['manufacturer'] = $html->find('ul#productDetailsList', 0)->find('li', 1)->plaintext;
  $item['manufacturer'] = explode(":", $item['manufacturer']);
  $item['manufacturer'] = trim($item['manufacturer'][1]);
  foreach($html->find('img') as $img)
  {
   if($img->alt == $item['title'])
   {
    $item['img_sm'] = $img->src;
    $thumb_width = $img->width;
    $thumb_height = $img->height;
   }
  }

  $sm_img_src = "http://XXXXXXXXXX.com/".$item['img_sm'];
  $lg_img_src = "http://XXXXXXXXXX.com/index.php?main_page=popup_image&pID=".$i;

  $ext = strrchr($item['img_sm'], '.');

  $filename = $item['model'] . $ext;
  $new_sm = "./rip_images/small/{$filename}";
  $new_lg = "./rip_images/large/{$filename}";

  $item['image'] = $filename;

  $file = file_get_contents($lg_img_src);
  $f = fopen($new_lg,'w+');
  fwrite($f,$file);
  fclose($f);

  save($sm_img_src,$new_sm);

  $ret[] = $item;
 }

 $html->clear();
 unset($html);

 return $ret;
}

$i = 1;
$end = 9999999;

while($i < $end)
{
 $ret = scrape($i);

 foreach($ret as $v)
 {
  $item['title'] = $v['title'];
  $item['price'] = $v['price'];
  $item['desc'] = $v['desc'];
  $item['model'] = $v['model'];
  $item['manufacturer'] = $v['manufacturer'];
  $item['image'] = $v['image'];
  $item['cat'] = $v['cat'];
  $item['subcat'] = $v['subcat'];
 }

  //see if parent cat exists
  $sql = 'SELECT cat_id FROM ' . SHOP_CAT_TABLE . ' WHERE cat_name = "'.$db->sql_escape($item['cat']).'"';
  $result = $db->sql_query($sql);
  $parent = $db->sql_fetchrow($result);

  // if not exists
  if($parent['cat_id'] == '')
  {
   //add the parent cat to the db
   $sql_ary = array(
    'cat_name' => $item['cat'],
    'cat_parent' => 0
   );
   $sql = 'INSERT INTO '.SHOP_CAT_TABLE.' '.$db->sql_build_array('INSERT', $sql_ary);
   $db->sql_query($sql);
   $cat_id = $db->sql_nextid();

   //see if subcat exists
   $sql = 'SELECT cat_id FROM ' . SHOP_CAT_TABLE . ' WHERE cat_name = "'.$db->sql_escape($item['subcat']).'"';
   $result = $db->sql_query($sql);
   $row = $db->sql_fetchrow($result);
   // if not exists
   if($row['cat_id'] == '')
   {
    //add subcat to db
    $sql_ary = array(
     'cat_name' => $db->sql_escape($item['subcat']),
     'cat_parent' => $cat_id
    );
    $sql = 'INSERT INTO '.SHOP_CAT_TABLE.' '.$db->sql_build_array('INSERT', $sql_ary);
    $db->sql_query($sql);
    $item_cat = $db->sql_nextid();
   }
   else //if exists
   {
    $item_cat = $row['cat_id'];
   }
  }
  else //if parent cat exists
  {
   //see if subcat exists
   $sql = 'SELECT cat_id FROM ' . SHOP_CAT_TABLE . ' WHERE cat_name = "'.$db->sql_escape($item['subcat']).'"';
   $result = $db->sql_query($sql);
   $row = $db->sql_fetchrow($result);
   // if not exists
   if($row['cat_id'] == '')
   {
    //add the subcat to the db
    $sql_ary = array(
     'cat_name' => $db->sql_escape($item['subcat']),
     'cat_parent' => $parent['cat_id']
    );
    $sql = 'INSERT INTO '.SHOP_CAT_TABLE.' '.$db->sql_build_array('INSERT', $sql_ary);
    $db->sql_query($sql);
    $item_cat = $db->sql_nextid();
   }
   else //if exists
   {
    $item_cat = $row['cat_id'];
   }
  }

  $sql_ary = array(
   'item_title'      => $db->sql_escape($item['title']),
   'item_price'     => $db->sql_escape($item['price']),
   'item_desc'      => $db->sql_escape($item['desc']),
   'item_model' => $db->sql_escape($item['model']),
   'item_manufacturer' => $db->sql_escape($item['manufacturer']),
   'item_image' => $db->sql_escape($item['image']),
   'item_cat'  => $db->sql_escape($item_cat)
  );

  $sql = 'INSERT INTO ' . SHOP_ITEM_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);

  $db->sql_query($sql);
 $i++;
}

?>

Любые предложения о том, как очистить эти уведомления /ошибки и заставить скрипт перебирать страницы, правильно?Я почти уверен, что это что-то очень простое, что я пропускаю ...

Ответы [ 3 ]

0 голосов
/ 31 декабря 2010

Почему бы вам просто не проверить, не являются ли извлекаемые вами объекты нулевыми, прежде чем пытаться их использовать?

0 голосов
/ 31 декабря 2010

Ваши ошибки указывают на то, что вы не просматриваете правильный источник HTML.

Не удалось найти открытый текст свойства, поскольку #productName не было найдено.

Line 35:  $item['title'] = trim($html->find('#productName', 0)->plaintext);

Не удалось найтиСвойство открытого текста, потому что #productPrices не был найден.

Line 36:  $item['price'] = trim($html->find('#productPrices', 0)->plaintext);

При взрыве на «::» не был получен третий элемент

Line 38:  list($home, $item['cat'], $item['subcat'], $title) = explode("::", $item['cat']);

Fatal, Не удалось вызвать find ()на результат, потому что 'ul # productDetailsList не найден.

Line 42:  $item['model'] = $html->find('ul#productDetailsList', 0)->find('li', 0)->plaintext;

Я бы добавил две вещи в ваш скрипт: 1) отладочные дампы для записи необработанного HTML, который вы пытаетесь проанализировать, и 2) проверкичтобы увидеть, если находки успешны.

1) в строке 32:

// put the $url into a variable
$url = 'XXXXXXXXX.com/index.php?blahblah';
echo "$url<br>\n";  // echo it so you can see the progress
$html = file_get_html($url); 

// log for debugging if problems:
$log_file = tempnam('/tmp/', 'rip_log_');
file_put_contents($log_file, $url . "\n" . $html)

2) добавить проверку для каждой успешной находки.(пример):

$test = $html->find('#productName', 0);
if ($test) {
    $item['title'] = trim($test->plaintext);
} else {
    echo "Could not find #productName";
    // maybe call break?
    break;
}
0 голосов
/ 31 декабря 2010

Он не останавливается, он умирает из-за фатальной ошибки в строке 42.

Предупреждения поступают из этих строк:

35: $item['title'] = trim($html->find('#productName', 0)->plaintext);
36: $item['price'] = trim($html->find('#productPrices', 0)->plaintext);
37: $item['cat'] = $html->find('#navBreadCrumb', 0)->plaintext;
38: list($home, $item['cat'], $item['subcat'], $title) = explode("::", $item['cat']);
39: $item['cat'] = str_replace("&nbsp;", "", $item['cat']);
40: $item['subcat'] = str_replace("\n", "", str_replace("&nbsp;", "", $item['subcat']));
41: $item['desc'] = trim($html->find('#productDescription', 0)->plaintext);
42: $item['model'] = $html->find('ul#productDetailsList', 0)->find('li', 0)->plaintext;

Ваш сценарий не переходит со страницы нана странице, он проходит через все products_ids от 1 до 99999, и, очевидно, нет продукта с идентификатором 2, поэтому этот URL возвращает что-то неожиданное:

index.php?main_page=product_info&products_id='.$i.'&zenid=e4b7dde8de02e1df005d4549e2e3e529`

Так как вы ожидаете, что эта страница имеет ul#productDetailsList (иэто не так), и вызывается ->find() для него - сценарий умирает, потому что вы вызываете метод для null

Решение состоит в том, чтобы проверить, есть ли у страницы сначала определенные селекторы, и попытаться извлечь title, price, cat и т. Д., Только если они присутствуют

...