Avatar billede weeelo Nybegynder
31. oktober 2006 - 20:38 Der er 4 kommentarer og
1 løsning

Optimering af RSS-parser

Hej eksperter,

Jeg har følgende RSS-Parser, som indeholder en del feeds. Derfor kunne jeg godt tænke mig at høre om det er muligt at optimere scriptet. Her kommer det lige:

<html>
<head>
<title> Opdaterer nyhedslisten... </title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="refresh" content="60; URL=http://www.rssparser.dk/">
</head>
<body>
<h2>Opdaterer nyhedslisten...</h2>
<dl>
<?php

MYSQL-CONNECT

$insideitem = false;
$tag = "";
$title = "";
$description = "";
$link = "";

function startElement($parser, $name, $attrs) {
    global $insideitem, $tag, $title, $description, $link;
    if ($insideitem) {
        $tag = $name;
    } elseif ($name == "ITEM") {
        $insideitem = true;
    }
}

function endElement($parser, $name) {
    global $insideitem, $tag, $title, $category, $description, $link;
    $link = str_replace('&amp;', '&', $link);
    $n_url = mysql_query("SELECT id FROM rss_news WHERE url = '$link'");
    if (mysql_num_rows($n_url) > 0) { } else {
    $published = date(U);
    if ($name == "ITEM") {
        if ( preg_match( "§^http://www.feed1.dk/§", $link )) {
            printf("",
            trim($link),addslashes(trim($title)));
            printf("",addslashes(trim($description)));
            $insert = mysql_query("INSERT INTO rss_news VALUES ('$title', '$description', '$link', 'Feed1', '$published', '0', '0')");
        } if ( preg_match( "§^ttp://www.feed1.dk/§", $link )) {
            printf("",
            trim($link),addslashes(trim($title)));
            printf("",addslashes(trim($description)));
            $insert = mysql_query("INSERT INTO rss_news VALUES ('$title', '$description', '$link', 'Feed2', '$published', '0', '0')");
        } if ( preg_match( "§^ttp://www.etc.dk/§", $link )) {
            printf("",
            trim($link),trim($title));
            printf("",trim($description));
            $insert = mysql_query("INSERT INTO rss_news VALUES ('$title', '$description', '$link', 'Etc', '$published', '0', '0')");
        } else {
        }
        $title = "";
        $description = "";
        $category = "";
        $link = "";
        $insideitem = false;
    }
    }
}

function characterData($parser, $data) {
    $data = rtrim(utf8_decode($data));
    global $insideitem, $tag, $title, $category, $description, $link;
    if ($insideitem) {
    switch ($tag) {
        case "TITLE":
        $title .= $data;
        break;
        case "DESCRIPTION":
        $description .= $data;

        break;
        case "LINK":
        $link .= $data;
        break;
        case "CATEGORY":
        $category .= $data;
        break;
    }
    }
}
$feeds = Array(
        "feed1",
        "feed2",
        "etc"
        );
for ($i = 0; $i < count($feeds); $i++)
{
    $xml_parser = xml_parser_create();
    xml_set_element_handler($xml_parser, "startElement", "endElement");
    xml_set_character_data_handler($xml_parser, "characterData");

    $fp = fopen($feeds[$i], "r");
    if ($fp !== false)
    {
        while ($data = fread($fp, 4096))
            xml_parse($xml_parser, $data, feof($fp));
        fclose($fp);
    }

    xml_parser_free($xml_parser);
}
?>
</dl>
</body>
</html>

Scriptet køres ved hjælp af CRON hvert minut, men en gang imellem springer den nyheder over. Der er ikke umiddelbart noget mønster i dem, der indsættes i databasen med forsinkelse.

Er der nogle der kan hjælpe mig med at optimere scriptet? Jeg giver gerne flere point, såfremt det er det, der skal til :)

MVH Weeelo
Avatar billede viper_killerguy Nybegynder
01. november 2006 - 01:02 #1
istedet for at kører så mange mysql_query("insert ..") burde du samle dem.

istedet for mysql_query("insert ..."):
$dbInserts[] = array($title, $description, $link, $feedname, $published, $bool1, $bool2);

og efter while(... mysql_fetch_...) {
$sql = "INSERT INTO rss_news VALUES";
if (!is_array($dbInserts))
  $dbInserts = array();
foreach($dbInserts as $i)
  $sql .= " ('$i[0]', '$i[1]', '$i[2]', '$i[3]', '$i[4]', '$i[5]', '$i[6]', '$i[7]'), ";
$sql = substr($sql, 0, -1);
mysql_query($sql) or trigger_error(mysql_error(), E_USER_ERROR);
Avatar billede viper_killerguy Nybegynder
01. november 2006 - 01:04 #2
$sql = substr($sql, 0, -2)
...mente jeg.

Hmm, der er egentligt også en extra " " uden grund, men det er ligemeget.
Avatar billede weeelo Nybegynder
01. november 2006 - 12:41 #3
Det var lige præcis sådan noget jeg tænkte på. Ser det her fornuftigt ud?

<html>
<head>
<title> Opdaterer nyhedslisten... </title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="refresh" content="60; URL=http://www.rssparser.dk/">
</head>
<body>
<h2>Opdaterer nyhedslisten...</h2>
<dl>
<?php

MYSQL-CONNECT

$insideitem = false;
$tag = "";
$title = "";
$description = "";
$link = "";

function startElement($parser, $name, $attrs) {
    global $insideitem, $tag, $title, $description, $link;
    if ($insideitem) {
        $tag = $name;
    } elseif ($name == "ITEM") {
        $insideitem = true;
    }
}

function endElement($parser, $name) {
    global $insideitem, $tag, $title, $category, $description, $link;
    $link = str_replace('&amp;', '&', $link);
    $n_url = mysql_query("SELECT id FROM rss_news WHERE url = '$link'");
    if (mysql_num_rows($n_url) > 0) { } else {
    $published = date(U);
    $bool1 = "0";
    $bool2 = "0";
    if ($name == "ITEM") {
        if ( preg_match( "§^http://www.feed1.dk/§", $link )) {
            printf("",
            trim($link),addslashes(trim($title)));
            printf("",addslashes(trim($description)));
            $feedname = "Feed1";
            $dbInserts[] = array($title, $description, $link, $feedname, $published, $bool1, $bool2);
        } if ( preg_match( "§^ttp://www.feed1.dk/§", $link )) {
            printf("",
            trim($link),addslashes(trim($title)));
            printf("",addslashes(trim($description)));
            $feedname = "Feed2";
            $dbInserts[] = array($title, $description, $link, $feedname, $published, $bool1, $bool2);
        } if ( preg_match( "§^ttp://www.etc.dk/§", $link )) {
            printf("",
            trim($link),trim($title));
            printf("",trim($description));
            $feedname = "Etc";
            $dbInserts[] = array($title, $description, $link, $feedname, $published, $bool1, $bool2);
        } else {
        }
        $title = "";
        $description = "";
        $category = "";
        $link = "";
        $insideitem = false;
    }
    while ( mysql_fetch_array( $dbInserts ) ) {
    $sql = "INSERT INTO rss_news VALUES";
    if (!is_array($dbInserts))
      $dbInserts = array();
    foreach($dbInserts as $i)
      $sql .= " ('$i[0]', '$i[1]', '$i[2]', '$i[3]', '$i[4]', '$i[5]', '$i[6]', '$i[7]'), ";
    $sql = substr($sql, 0, -2);
    mysql_query($sql) or trigger_error(mysql_error(), E_USER_ERROR);
    }
}

function characterData($parser, $data) {
    $data = rtrim(utf8_decode($data));
    global $insideitem, $tag, $title, $category, $description, $link;
    if ($insideitem) {
    switch ($tag) {
        case "TITLE":
        $title .= $data;
        break;
        case "DESCRIPTION":
        $description .= $data;

        break;
        case "LINK":
        $link .= $data;
        break;
        case "CATEGORY":
        $category .= $data;
        break;
    }
    }
}
$feeds = Array(
        "feed1",
        "feed2",
        "etc"
        );
for ($i = 0; $i < count($feeds); $i++)
{
    $xml_parser = xml_parser_create();
    xml_set_element_handler($xml_parser, "startElement", "endElement");
    xml_set_character_data_handler($xml_parser, "characterData");

    $fp = fopen($feeds[$i], "r");
    if ($fp !== false)
    {
        while ($data = fread($fp, 4096))
            xml_parse($xml_parser, $data, feof($fp));
        fclose($fp);
    }

    xml_parser_free($xml_parser);
}
?>
</dl>
</body>
</html>

Og hvis jeg gerne vil have den til at fortsætte selvom et feed har fejl, skal jeg så bare fjerne "or trigger_error(mysql_error(), E_USER_ERROR)'"?
Avatar billede viper_killerguy Nybegynder
01. november 2006 - 19:39 #4
Oh, det skal gøres lidt anderledes.

for det første burde du nok tilføje $dbInserts til global i endElement()

og så flytte det her:
    while ( mysql_fetch_array( $dbInserts ) ) {
    $sql = "INSERT INTO rss_news VALUES";
    if (!is_array($dbInserts))
      $dbInserts = array();
    foreach($dbInserts as $i)
      $sql .= " ('$i[0]', '$i[1]', '$i[2]', '$i[3]', '$i[4]', '$i[5]', '$i[6]', '$i[7]'), ";
    $sql = substr($sql, 0, -2);
    mysql_query($sql) or trigger_error(mysql_error(), E_USER_ERROR);
    }
ned til efter for ($i = 0; $i < count($feeds); $i++)

og så skal du fjerne den
while ( mysql_fetch_array( $dbInserts ) ) { ... }
der er rundt om det $dbInserts kode.
Avatar billede weeelo Nybegynder
11. november 2006 - 21:26 #5
Hej igen,

Jeg har prøvet med følgende, men kunne ikke få det til at virke:

<html>
<head>
<title> Opdaterer nyhedslisten... </title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="refresh" content="60; URL=http://www.rssparser.dk/">
</head>
<body>
<h2>Opdaterer nyhedslisten...</h2>
<dl>
<?php

MYSQL-CONNECT

$insideitem = false;
$tag = "";
$title = "";
$description = "";
$link = "";

function startElement($parser, $name, $attrs) {
    global $insideitem, $tag, $title, $description, $link;
    if ($insideitem) {
        $tag = $name;
    } elseif ($name == "ITEM") {
        $insideitem = true;
    }
}

function endElement($parser, $name) {
    global $insideitem, $tag, $title, $category, $description, $link, $dbInserts;
    $link = str_replace('&amp;', '&', $link);
    $n_url = mysql_query("SELECT id FROM rss_news WHERE url = '$link'");
    if (mysql_num_rows($n_url) > 0) { } else {
    $published = date(U);
    $bool1 = "0";
    $bool2 = "0";
    if ($name == "ITEM") {
        if ( preg_match( "§^http://www.feed1.dk/§", $link )) {
            printf("",
            trim($link),addslashes(trim($title)));
            printf("",addslashes(trim($description)));
            $feedname = "Feed1";
            $dbInserts[] = array($title, $description, $link, $feedname, $published, $bool1, $bool2);
        } if ( preg_match( "§^ttp://www.feed1.dk/§", $link )) {
            printf("",
            trim($link),addslashes(trim($title)));
            printf("",addslashes(trim($description)));
            $feedname = "Feed2";
            $dbInserts[] = array($title, $description, $link, $feedname, $published, $bool1, $bool2);
        } if ( preg_match( "§^ttp://www.etc.dk/§", $link )) {
            printf("",
            trim($link),trim($title));
            printf("",trim($description));
            $feedname = "Etc";
            $dbInserts[] = array($title, $description, $link, $feedname, $published, $bool1, $bool2);
        } else {
        }
        $title = "";
        $description = "";
        $category = "";
        $link = "";
        $insideitem = false;
    }
}

function characterData($parser, $data) {
    $data = rtrim(utf8_decode($data));
    global $insideitem, $tag, $title, $category, $description, $link;
    if ($insideitem) {
    switch ($tag) {
        case "TITLE":
        $title .= $data;
        break;
        case "DESCRIPTION":
        $description .= $data;

        break;
        case "LINK":
        $link .= $data;
        break;
        case "CATEGORY":
        $category .= $data;
        break;
    }
    }
}
$feeds = Array(
        "feed1",
        "feed2",
        "etc"
        );
for ($i = 0; $i < count($feeds); $i++)
{
    $sql = "INSERT INTO rss_news VALUES";
    if (!is_array($dbInserts))
      $dbInserts = array();
    foreach($dbInserts as $i)
      $sql .= " ('$i[0]', '$i[1]', '$i[2]', '$i[3]', '$i[4]', '$i[5]', '$i[6]', '$i[7]'), ";
    $sql = substr($sql, 0, -2);
    mysql_query($sql) or trigger_error(mysql_error(), E_USER_ERROR);

    $xml_parser = xml_parser_create();
    xml_set_element_handler($xml_parser, "startElement", "endElement");
    xml_set_character_data_handler($xml_parser, "characterData");

    $fp = fopen($feeds[$i], "r");
    if ($fp !== false)
    {
        while ($data = fread($fp, 4096))
            xml_parse($xml_parser, $data, feof($fp));
        fclose($fp);
    }

    xml_parser_free($xml_parser);
}
?>
</dl>
</body>
</html>
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester