3
\$\begingroup\$

I created this script to take informations "at-the-moment" of this site:

Pictures of name channel
Name of channel
Pictures channel
Times
Title
Type

My script (Work):

<?php

$url="http://www.programme-tv.net/programme/toutes-les-chaines/en-ce-moment.html#Grandes%20cha%C3%AEnes";
$code_page = file_get_contents($url);

preg_match_all('/<div class="channelItem">(.*?)<img src="(.*?)" alt="Le programme de (.*?)" width="70" height="30">/is', $code_page, $chaines);
preg_match_all('/<div class="show (.*?) at-the-moment current (.*?)">(.*?)<div class="show-infos">(.*?)<\/div>/is', $code_page, $channels);

$i=0;
foreach ($channels as $channel) {
    if($i==3){
        for ($j=0; $j < 38; $j++) {
            preg_match_all('/<span class="(.*?)"><img src="http:\/\/static.programme-tv.net\/var\/epgs\/169\/80x\/(.*?)" alt="(.*?)" width="80" \/><\/span>/', $channel[$j], $image[$j]); 
        }
    }

if($i==4){
        for ($j=0; $j < 38; $j++) { 
            preg_match_all('/<p class="time">(.*?)<\/p>/', $channel[$j], $time[$j]);
            preg_match_all('/<p class="title">(.*?)<\/p>/', $channel[$j], $title[$j]);
            preg_match_all('/<p class="type">(.*?)<\/p>/', $channel[$j], $type[$j]);
        }
    }
    $i++;
}

for ($i=0; $i < 38; $i++) {
    $test = strpos($chaines[2][$i],' </div>');
    if($test != true){
        echo 'Chaines images: <img src="'.$chaines[2][$i].'"/><br />';
        echo 'Chaines: '.$chaines[3][$i].'<br />';
        echo 'image : <img src="http://static.programme-tv.net/var/epgs/169/80x/'.$image[$i][2][0].'" /><br />'; 
        echo 'Temps : '.trim($time[$i][1][0]).'<br />';
        echo 'Titre : '.substr($title[$i][1][0], strpos($title[$i][1][0], '>') + 1, strrpos($title[$i][1][0], '<')).'<br />';
        echo 'Type : '.$type[$i][1][0].'<br />';
        echo '<hr>';
    }
}
?>

I would like to improve and find a better regular expression pattern because I use 6 regular expression pattern.

\$\endgroup\$
3
  • \$\begingroup\$ What do you mean by "pattern"? I assume you mean regular expression pattern? Additionally, you say that you're using 4 but I can see 6. \$\endgroup\$ Commented Dec 26, 2014 at 13:56
  • \$\begingroup\$ Oops yes it's 6 ^^ sorry. And yes I mean "regular expression pattern". \$\endgroup\$
    – Pilipe
    Commented Dec 26, 2014 at 14:04
  • 1
    \$\begingroup\$ Please read: What you may and may not do after receiving answers - consider asking a follow-on question. Your edits herehave been rolled back \$\endgroup\$
    – rolfl
    Commented Dec 27, 2014 at 12:42

3 Answers 3

5
\$\begingroup\$

To be honest I don't think your current way of handling is 'clean'. But I would suggest you to use a HTML DOM parser. I took the liberty to google it for you and http://simplehtmldom.sourceforge.net/ seems quite what you need.

It's a PHP HTML parser, which allows you to write

// Find all element which class=foo
$ret = $html->find('.at-the-moment');

instead of

preg_match_all('/<div class="show (.*?) at-the-moment current (.*?)">(.*?)<div class="show-infos">(.*?)<\/div>/is', $code_page, $channels);

Also your other regexes can be switched (read the documentation)

To be honest, I never used this library before, but I've worked with beautifulsoup which is a Python equivalent, which would do the trick for you perfectly. (source: http://www.givegoodweb.com/post/210/html-parser-for-php)

Wishing you the best!

\$\endgroup\$
3
  • \$\begingroup\$ +1, Don't parse HTML with Regular expressions! \$\endgroup\$ Commented Dec 26, 2014 at 15:23
  • \$\begingroup\$ Thank you. I try to use DOMDocument at the moment. And later your HTML DOM parser for watch the difference. In what conditions does one uses regular expressions? \$\endgroup\$
    – Pilipe
    Commented Dec 26, 2014 at 15:56
  • \$\begingroup\$ This is a hard question. Regular Expressions can do awesome things in just a blink of a second, however they are hard to maintain and to check all possible scenario's. A beter question is to ask 'when shouldn't you use them?' -> programmers.stackexchange.com/questions/113237/… As you can see 'parsing HTML with regexp' is mentioned as first ;) \$\endgroup\$
    – DJanssens
    Commented Dec 26, 2014 at 16:08
1
\$\begingroup\$

Don't parse HTML with regular expressions

First of all, don't parse HTML with regular expressions.

Second of all, don't parse HTML with regular expressions.

Indentation

Pay attention to correct indentation, for example in this code:

foreach ($channels as $channel) {
    if($i==3){
        // ...
    }

if($i==4){

The indent level if this last if statement is unexpected. It gives the impression that it's outside of the foreach loop, but no it's still inside. Be careful, this kind of thing can seriously hurt readability.

Using an alternative pattern separator instead of ///

You could simplify many of your patterns by using a different separator instead of /, for example |:

preg_match_all('|<span class="(.*?)"><img src="http://static.programme-tv.net/var/epgs/169/80x/(.*?)" alt="(.*?)" width="80" /></span>|', $channel[$j], $image[$j]); 

This way you don't need to escape so many embedded /, which is a lot easier on the eyes too.

Readability

I recommend to borrow from the formatting conventions of other languages and put spaces around operators and parentheses. Instead of this:

if($i==4){

Write like this:

if ($i == 4) {

Conditions on boolean expressions

When working with boolean values, you don't need the == or != operators, you can use the boolean values directly. Instead of this:

if($test != true){

You can write simply:

if (!$test) {
\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the constructive comments and for the tips. I did not know for the patterns. I have my script properly indent but on this forum the indent have changed :( \$\endgroup\$
    – Pilipe
    Commented Dec 27, 2014 at 7:47
0
\$\begingroup\$

Script with DOMDocument :

<?php

    $url="http://www.programme-tv.net/programme/en-ce-moment.html#TNT%20-%20Cha%C3%AEnes%20Gratuites";
    $html = file_get_contents($url);

    $dom = new DOMDocument;
    @$dom->loadHTML($html);

    $classname = 'at-the-moment';
    $xpath = new DOMXPath($dom);
    $datas = $xpath->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");

    foreach ($datas as $data) {
        $tags = $data->getElementsByTagName('img');
        if($tags->length === 1){
            foreach ($tags as $tag) {
                $infos['image_en_cours'][] = $tag->getAttribute('src');
            }
        }
        else
        {
            $infos['image_en_cours'][] = 'no_image';
        }

        $xml = $data->ownerDocument->saveXML($data);
        $dom->loadHTML($xml);
        $xpath = new DOMXPath($dom);

        $classname = 'title';
        $titles = $xpath->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
        foreach ($titles as $title) {
            $infos['titre'][] = $title->nodeValue;
        }

        $classname = 'time';
        $times = $xpath->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
        foreach ($times as $time) {
            $infos['temps'][] = $time->nodeValue;
        }

        $classname = 'type';
        $types = $xpath->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
        foreach ($types as $type) {
            $infos['types'][] = $type->nodeValue;
        }
    }

    @$dom->loadHTML($html);
    $xpath = new DOMXPath($dom);
    $classname = 'channel_logo';
    $channels = $xpath->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");

    foreach ($channels as $channel) {
        $datas = $channel->getElementsByTagName('img');
        foreach ($datas as $data) {
            $infos['image_nom_television'][] = $data->getAttribute('src');
            $infos['nom_chaine'][] = substr($data->getAttribute('alt'), 16);
        }
    }

    for ($i = 0; $i < 38; $i++) { 
        echo 'Image de la chaine : <img src="'.$infos['image_nom_television'][$i].'" alt="'.$infos['nom_chaine'][$i].'" /><br />';
        echo 'Nom de la chaine : '.$infos['nom_chaine'][$i].'<br />';
        echo utf8_decode('Image en cours : <img src="'.$infos['image_en_cours'][$i].'" alt="'.$infos['titre'][$i].'" /><br />');
        echo utf8_decode('Titre : '.$infos['titre'][$i].'<br />');
        echo 'Commencé à : '.$infos['temps'][$i].'<br />';
        echo utf8_decode('Genre : '.$infos['types'][$i].'<br />');
        echo '<hr>';
    }

?>

I think this script is better than the first. What do you think ? you see an optimization ?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.