/ Forside / Teknologi / Udvikling / PHP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
PHP
#NavnPoint
rfh 3959
natmaden 3372
poul_from 3310
funbreak 2700
stone47 2230
Jin2k 1960
Angband 1743
Bjerner 1249
refi 1185
10  Interkril.. 1146
Eliminiering af tekster der indeholder bes~
Fra : Birger Sørensen


Dato : 25-08-08 17:14

Jeg har min egen lille besøgs-statistik.

Ved gennemgang ser man ret så mange besøg fra søgemaskiner - Googlebot,
msnbot, Yahoo! Slurp for at nævne nogle.

For at eliminere dem fra tællere, har jeg gjort denne lille funktion:


function IsSkipAgent() {
   global $link;
   $res = false;
   $ip_ag = getenv( "HTTP_USER_AGENT");
   $query = "SELECT * FROM no_agent";
   if ( $ag_rez = mysql_query( $query, $link)) {
      while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {
         $res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);
         }
      }
   return $res;
   }


Tabellen no_agent indeholder i attributen 'agent' de strenge, der ikke
må forekomme i user-agent - eller rettere, hvis disse strenge findes,
skal besøget ikke tælles med. Fumtionen skal altså returnere sand, hvis
en af teksterne finde is USER_AGENT, og falsk, ellers.
no_agent ser pt, sådan ud:

Googlebot
Slurp
libwww-perl
msnbot
Googlebot
Anonymouse
MJ12bot

Og det virker faktisk fortrinligt - bortset fra, at Yahoo! Slurp, ikke
bliver filtreret fra. ( IP er hvadsomhelst der starter med 74.6 - somme
tider også 67.195 )

HTTP_USER_AGENT kan f.eks. se sådan ud :
Mozilla/5.0 (compatible; Yahoo! Slurp;
http://help.yahoo.com/help/us/ysearch/slurp)

strpos skal returnere falsk, hvis 'den forbudte streng' ikke findes i
USER_AGENT. Men det gør den (tilsyneladende) ikke, når der står Yahoo!
Slurp...

Jeg har forsøgt med hele teksten 'Yahoo! Slurp', med 'Yahoo!' og
'Yahoo' ( så bliver visse besøgende med Yahoo! toolbar installeret
filtreret fra - men ikke Yahoo! Slurp) og med kun 'Slurp'.
Men ingen af dem virker! Yahoo! Slurp optræder stadig i mine
statistikker.
Men det virker med de øvrige strenge - ingen af dem er med i
statistikkerne.

Nogen der kan gennemskue, eller har en ide om hvorfor?

Birger



 
 
Dan Storm (26-08-2008)
Kommentar
Fra : Dan Storm


Dato : 26-08-08 12:45

Birger Sørensen skrev:
> function IsSkipAgent() {
> global $link;
> $res = false;
> $ip_ag = getenv( "HTTP_USER_AGENT");
> $query = "SELECT * FROM no_agent";
> if ( $ag_rez = mysql_query( $query, $link)) {
> while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {
> $res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);
> }
> }
> return $res;
> }
>

Så'n lidt hurtigt skimtet igennem, så ser jeg en while løkke der bliver
kørt færdig?

så altså, det der sker er:

løkke(tjek "Mozilla/5.0 (compatible; Yahoo! Slurp;
http://help.yahoo.com/help/us/ysearch/slurp) ")
{
   Googlebot -> $res = false
   Slurp -> $res = true
   libwww-perl -> $res = false
   msnbot -> $res = false
   Anonymouse -> $res = false
   MJ12bot -> $res = false
}
return $res

I det her tilfælde vil $res være false, fordi løkken kørte videre?

Prøv at udskifte:
$res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);

med

if( strpos( $ip_ag, $ag_arr["agent"]) !== false)
   return true;

og skift dit
return $res;
ud med
return false;

--
Dan Storm - storm at err0r dot dk / http://err0r.dk

Tro ikke brugerne vil gøre noget for at undgå dit killfilter
- Så vigtig er du heller ikke!

Dan Storm (26-08-2008)
Kommentar
Fra : Dan Storm


Dato : 26-08-08 13:13

Dan Storm skrev:
> Birger Sørensen skrev:
>> function IsSkipAgent() {
>> global $link;
>> $res = false;
>> $ip_ag = getenv( "HTTP_USER_AGENT");
>> $query = "SELECT * FROM no_agent";
>> if ( $ag_rez = mysql_query( $query, $link)) {
>> while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {
>> $res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);
>> }
>> }
>> return $res;
>> }
>>
>
> Så'n lidt hurtigt skimtet igennem, så ser jeg en while løkke der bliver
> kørt færdig?

Næ, det var bare mig der havde kigget det for hurtigt igennem... nvm...

--
Dan Storm - storm at err0r dot dk / http://err0r.dk

Tro ikke brugerne vil gøre noget for at undgå dit killfilter
- Så vigtig er du heller ikke!

Birger Sørensen (26-08-2008)
Kommentar
Fra : Birger Sørensen


Dato : 26-08-08 13:32

Dan Storm kom med denne ide:
> Birger Sørensen skrev:
>> function IsSkipAgent() {
>> global $link;
>> $res = false;
>> $ip_ag = getenv( "HTTP_USER_AGENT");
>> $query = "SELECT * FROM no_agent";
>> if ( $ag_rez = mysql_query( $query, $link)) {
>> while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {
>> $res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);
>> }
>> }
>> return $res;
>> }
>>
>
> Så'n lidt hurtigt skimtet igennem, så ser jeg en while løkke der bliver kørt
> færdig?
>
> så altså, det der sker er:
>
> løkke(tjek "Mozilla/5.0 (compatible; Yahoo! Slurp;
> http://help.yahoo.com/help/us/ysearch/slurp) ")
> {
>    Googlebot -> $res = false
>    Slurp -> $res = true
>    libwww-perl -> $res = false
>    msnbot -> $res = false
>    Anonymouse -> $res = false
>    MJ12bot -> $res = false
> }
> return $res
>
> I det her tilfælde vil $res være false, fordi løkken kørte videre?
>
> Prøv at udskifte:
> $res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);
>
> med
>
> if( strpos( $ip_ag, $ag_arr["agent"]) !== false)
>    return true;
>
> og skift dit
> return $res;
> ud med
> return false;

while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {...}

Hvis $res bliver true, afbrydes løkken.

IMHO er return midt i koder, ligesom break, en uskik der gør koden
mindre overskuelig end det er nødvendigt.
Men jeg er nok bare gammeldags ;>)

Jeg vil dog prøve dit forslag..

Birger



Dan Storm (26-08-2008)
Kommentar
Fra : Dan Storm


Dato : 26-08-08 14:32

Birger Sørensen skrev:
> while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {...}
>
> Hvis $res bliver true, afbrydes løkken.

Ja, jeg så det godt lidt for sent... ;)

>
> IMHO er return midt i koder, ligesom break, en uskik der gør koden
> mindre overskuelig end det er nødvendigt.
> Men jeg er nok bare gammeldags ;>)

Det er nok et spørgsmål om vane. :)

Istedet for at lade løkken rende igennem vil jeg hellere bruge en return
eller break, så længe det giver mig det forventede resultat. For mig
virker det både overskueligt og som den rigtige måde at afslutte et
funktionskald på. Men det er jo også bare den vane jeg har tillagt mig.



--
Dan Storm - storm at err0r dot dk / http://err0r.dk

Tro ikke brugerne vil gøre noget for at undgå dit killfilter
- Så vigtig er du heller ikke!

Birger Sørensen (26-08-2008)
Kommentar
Fra : Birger Sørensen


Dato : 26-08-08 15:24

Dan Storm forklarede den 26-08-2008:
> Birger Sørensen skrev:
>> while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {...}
>>
>> Hvis $res bliver true, afbrydes løkken.
>
> Ja, jeg så det godt lidt for sent... ;)
>
>>
>> IMHO er return midt i koder, ligesom break, en uskik der gør koden mindre
>> overskuelig end det er nødvendigt.
>> Men jeg er nok bare gammeldags ;>)
>
> Det er nok et spørgsmål om vane. :)
>
> Istedet for at lade løkken rende igennem vil jeg hellere bruge en return
> eller break, så længe det giver mig det forventede resultat. For mig virker
> det både overskueligt og som den rigtige måde at afslutte et funktionskald
> på. Men det er jo også bare den vane jeg har tillagt mig.



Vanens magt...

Ser i øvrigt ud somom, problemet slet ikke ligger i den funktion.

Rutinen der registrerer besøgende, kaldte IsSkipAgent() sådan :
if ( !IsSkipAgent()) { ...}
det har jeg nu ændret til
if ( IsSkipAgent() === false) {...}
og det ser ud til at gøre en forskel.

Fatter det ikke rigtigt. IsSkipAgent, burde da altid returnere en
boolean:
$res = !( strpos(...) === false);
burde i min bog returmere falsk, hvis strpos() returnerer en bool falsk
- og sand hvis strpos() returnerer hvad som helst andet..

Nu kan man jo ikke selv bestemme hvornår man vil have besøg af
søgemaskinerne - men der er ikke registreret nogen siden denne ændring
Kan nok ikke være sikker før en gang i morgen - ellers skal jeg til
også at registrere de afviste..

Birger



Dan Storm (27-08-2008)
Kommentar
Fra : Dan Storm


Dato : 27-08-08 07:50

Birger Sørensen skrev:
>
> Vanens magt...
>
> Ser i øvrigt ud somom, problemet slet ikke ligger i den funktion.
>
> Rutinen der registrerer besøgende, kaldte IsSkipAgent() sådan :
> if ( !IsSkipAgent()) { ...}
> det har jeg nu ændret til
> if ( IsSkipAgent() === false) {...}
> og det ser ud til at gøre en forskel.
>
> Fatter det ikke rigtigt. IsSkipAgent, burde da altid returnere en boolean:
> $res = !( strpos(...) === false);
> burde i min bog returmere falsk, hvis strpos() returnerer en bool falsk
> - og sand hvis strpos() returnerer hvad som helst andet..

En hurtig test af det du har lavet viser nu også mig at IsSkipAgent()
returnerer en boolean. At du så skal bruge === forstår jeg så heller
ikke, men det kan måske forklares af nogen som kan gå et niveau længere ned?

>
> Nu kan man jo ikke selv bestemme hvornår man vil have besøg af
> søgemaskinerne - men der er ikke registreret nogen siden denne ændring
> Kan nok ikke være sikker før en gang i morgen - ellers skal jeg til også
> at registrere de afviste..

Well, lad høre når du har fået resultaterne - jeg er da lidt spændt på
at høre om du fik succes med ===


--
Dan Storm - storm at err0r dot dk / http://err0r.dk

Tro ikke brugerne vil gøre noget for at undgå dit killfilter
- Så vigtig er du heller ikke!

Bertel Lund Hansen (27-08-2008)
Kommentar
Fra : Bertel Lund Hansen


Dato : 27-08-08 09:52

Dan Storm skrev:

> returnerer en boolean. At du så skal bruge === forstår jeg så heller
> ikke, men det kan måske forklares af nogen som kan gå et niveau længere ned?

Jeg har ikke overblik over de rutiner i diskuterer, men jeg
kender brugen af lighedstegn.

To = bruger en 'løs' evaluering hvor 0 og '' opfattes på samme
måde som false.
Tre = kræver at typen er rigtig og vil ikke returnere boolesk
false ved 0 og ''. Eksempel:

   $brevtekst="Hej Moster";
   $searchfor="Hej";

   if (strpos($brevtekst,$searchfor))
      echo "Du har husket en hilsen.";
   else
      echo "Husk at skrive ".$searchfor;

Den test går galt idet Hej's position jo er 0. Output er derfor:

          Husk at skrive Hej

Denne test lider af samme fejl:

   if (strpos($brevtekst,$searchfor)!=false)

Den rigtige skal se sådan ud:

   if (strpos($brevtekst,$searchfor)!==false)

Den aflæser position 0 som et svar der ikke er falsk.

--
Bertel
http://bertel.lundhansen.dk/      FIDUSO: http://fiduso.dk/

Birger Sørensen (27-08-2008)
Kommentar
Fra : Birger Sørensen


Dato : 27-08-08 12:02

Bertel Lund Hansen udtrykte præcist:
> Dan Storm skrev:
>
>> returnerer en boolean. At du så skal bruge === forstår jeg så heller
>> ikke, men det kan måske forklares af nogen som kan gå et niveau længere ned?
>
> Jeg har ikke overblik over de rutiner i diskuterer, men jeg
> kender brugen af lighedstegn.
>
> To = bruger en 'løs' evaluering hvor 0 og '' opfattes på samme
> måde som false.
> Tre = kræver at typen er rigtig og vil ikke returnere boolesk
> false ved 0 og ''. Eksempel:
>
>    $brevtekst="Hej Moster";
>    $searchfor="Hej";
>
>    if (strpos($brevtekst,$searchfor))
>       echo "Du har husket en hilsen.";
>    else
>       echo "Husk at skrive ".$searchfor;
>
> Den test går galt idet Hej's position jo er 0. Output er derfor:
>
>           Husk at skrive Hej
>
> Denne test lider af samme fejl:
>
>    if (strpos($brevtekst,$searchfor)!=false)
>
> Den rigtige skal se sådan ud:
>
>    if (strpos($brevtekst,$searchfor)!==false)
>
> Den aflæser position 0 som et svar der ikke er falsk.

Problemet er, at

$res = !( strpos( $ip_ag, $ag_arr[ 'agent']) === false);
og/eller
$res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);

returnerer falsk, også når $ag_arr[ 'agent'] faktisk er i $ip_ag..


Jeg kan konstatere i dag, at den ændrede sammenligning ( fra
!IsSkipAgent() til IsSkipAgnet === false ) ikke gør nogen forskel.

Fatter nada.
Vender tilbage, når jeg har noget...

Birger



Bertel Lund Hansen (27-08-2008)
Kommentar
Fra : Bertel Lund Hansen


Dato : 27-08-08 12:53

Birger Sørensen skrev:

> Problemet er, at

> $res = !( strpos( $ip_ag, $ag_arr[ 'agent']) === false);
> og/eller
> $res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);

> returnerer falsk, også når $ag_arr[ 'agent'] faktisk er i $ip_ag..

Prøv at udskrive "#".$ip_ag."#" og "#".$ag_arr[ 'agent']."#". Det
kan afsløre overraskende blanktegn.

--
Bertel
http://bertel.lundhansen.dk/      FIDUSO: http://fiduso.dk/

Birger Sørensen (27-08-2008)
Kommentar
Fra : Birger Sørensen


Dato : 27-08-08 13:29

Bertel Lund Hansen kom med denne ide:
> Birger Sørensen skrev:
>
>> Problemet er, at
>
>> $res = !( strpos( $ip_ag, $ag_arr[ 'agent']) === false);
>> og/eller
>> $res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);
>
>> returnerer falsk, også når $ag_arr[ 'agent'] faktisk er i $ip_ag..
>
> Prøv at udskrive "#".$ip_ag."#" og "#".$ag_arr[ 'agent']."#". Det
> kan afsløre overraskende blanktegn.

Forhåbentlig ikke..
$ip_ag hentees som getenv( "HTTP_USER_AGENT") og $ag_arr[ 'agent']
kommer fra en database.
Det er ikke lige nemt at udskrive - det sker når der er besøgende på
siden, og det jeg vil detektere er om denne besøgende er en søgemaskine
eller anden form for bot... udskriften med interessante værdier vil
altså ikke blive sendt et andet sted hen...
Jeg gemmer værdierne i en database. Og her ser de rigtige ud.
Jeg er imidlertid inde på at det muligvis er arrayet, genereret fra en
resource fra databasen, som strpos ikke får rigtig fat i. Slurp kommer
igennem hver gang. Og der har i løbet af natten været besøg fra nogle
af de andre - nogle fanges, andre ikke, selv fra samme bot.

Så jeg har ændret til
while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {
   $ag_str = $ag_arr[ 'agent'];
   $res = !( strpos( $ip_ag, $ag_str) === false);
   }
og venter så bare på at der skal komme nogle flere besøg fra de bots,
så jeg kan se om det gør en forkel.
Skal nok opdatere

Birger



Birger Sørensen (28-08-2008)
Kommentar
Fra : Birger Sørensen


Dato : 28-08-08 09:14

Birger Sørensen har bragt dette til os:
> Bertel Lund Hansen kom med denne ide:
>> Birger Sørensen skrev:
>>
>>> Problemet er, at
>>
>>> $res = !( strpos( $ip_ag, $ag_arr[ 'agent']) === false);
>>> og/eller
>>> $res = ( strpos( $ip_ag, $ag_arr[ 'agent']) !== false);
>>
>>> returnerer falsk, også når $ag_arr[ 'agent'] faktisk er i $ip_ag..
>>
>> Prøv at udskrive "#".$ip_ag."#" og "#".$ag_arr[ 'agent']."#". Det
>> kan afsløre overraskende blanktegn.
>
> Forhåbentlig ikke..
> $ip_ag hentees som getenv( "HTTP_USER_AGENT") og $ag_arr[ 'agent'] kommer fra
> en database.
> Det er ikke lige nemt at udskrive - det sker når der er besøgende på siden,
> og det jeg vil detektere er om denne besøgende er en søgemaskine eller anden
> form for bot... udskriften med interessante værdier vil altså ikke blive
> sendt et andet sted hen...
> Jeg gemmer værdierne i en database. Og her ser de rigtige ud.
> Jeg er imidlertid inde på at det muligvis er arrayet, genereret fra en
> resource fra databasen, som strpos ikke får rigtig fat i. Slurp kommer
> igennem hver gang. Og der har i løbet af natten været besøg fra nogle af de
> andre - nogle fanges, andre ikke, selv fra samme bot.
>
> Så jeg har ændret til
> while (( !$res) && ( $ag_arr = mysql_fetch_assoc( $ag_rez))) {
>    $ag_str = $ag_arr[ 'agent'];
>    $res = !( strpos( $ip_ag, $ag_str) === false);
>    }
> og venter så bare på at der skal komme nogle flere besøg fra de bots, så jeg
> kan se om det gør en forkel.
> Skal nok opdatere
>
> Birger


Pinligt, pinligt.

Sorteringen virker som den skal, og strpos() - og min rutine - leverer
også de rigtige variabel typer og værdier.
Det kræver blot, at data der sammelignes med hentes fra den rigtige
tabel!
Beklager at have spildt jeres tid på det her, og takker for inputtene.

Birger



Bertel Lund Hansen (28-08-2008)
Kommentar
Fra : Bertel Lund Hansen


Dato : 28-08-08 09:26

Birger Sørensen skrev:

> Beklager at have spildt jeres tid på det her, og takker for inputtene.

Det skal du ikke beklage. Ifølge en bog om programmering som jeg
læste i tidernes morgen, så får 99 % af kodefejlene programmøren
til at slå sig for panden og udbryde "Hvordan kunne jeg dog
skrive sådan noget sludder?".

Mange af os andre har også spurgt om noget vi selv fandt
løsningen på kort efter.

--
Bertel
http://bertel.lundhansen.dk/      FIDUSO: http://fiduso.dk/

Dan Storm (28-08-2008)
Kommentar
Fra : Dan Storm


Dato : 28-08-08 11:14

Birger Sørensen skrev:
> Pinligt, pinligt.
>
> Sorteringen virker som den skal, og strpos() - og min rutine - leverer
> også de rigtige variabel typer og værdier.
> Det kræver blot, at data der sammelignes med hentes fra den rigtige tabel!
> Beklager at have spildt jeres tid på det her, og takker for inputtene.
>
> Birger
>
>

Sådan går det jo nogengange ;)

Men beklage behøver du ikke, for vi andre gør jo det samme... :)

--
Dan Storm - storm at err0r dot dk / http://err0r.dk

Tro ikke brugerne vil gøre noget for at undgå dit killfilter
- Så vigtig er du heller ikke!

Dan Storm (27-08-2008)
Kommentar
Fra : Dan Storm


Dato : 27-08-08 12:56

Birger Sørensen skrev:
> Jeg kan konstatere i dag, at den ændrede sammenligning ( fra
> !IsSkipAgent() til IsSkipAgnet === false ) ikke gør nogen forskel.
>
> Fatter nada.
> Vender tilbage, når jeg har noget...
>

Nu har jeg forsøgt med den liste du angav tidligere (hurtig omskrivning
af din funktion, men idéen er den samme) og jeg får det ventede resultat
ud med 'Slurp'.

function IsSkipAgent() {
global $link;

   $ary = array(
      "Googlebot",
      "Slurp",
      "libwww-perl",
      "msnbot",
      "Anonymouse",
      "MJ12bot"
   );

$res = false;
$ip_ag = getenv("HTTP_USER_AGENT");
while ((!$res) && list(, $value) = each($ary)) {
   $res = ( strpos( $ip_ag, $value) !== false);
}

return $res;
}

Kan det være HTTP_USER_AGENT der snyder?


--
Dan Storm - storm at err0r dot dk / http://err0r.dk

Tro ikke brugerne vil gøre noget for at undgå dit killfilter
- Så vigtig er du heller ikke!

Birger Sørensen (27-08-2008)
Kommentar
Fra : Birger Sørensen


Dato : 27-08-08 13:29

Dan Storm sendte dette med sin computer:
> Birger Sørensen skrev:
>> Jeg kan konstatere i dag, at den ændrede sammenligning ( fra !IsSkipAgent()
>> til IsSkipAgnet === false ) ikke gør nogen forskel.
>>
>> Fatter nada.
>> Vender tilbage, når jeg har noget...
>>
>
> Nu har jeg forsøgt med den liste du angav tidligere (hurtig omskrivning af
> din funktion, men idéen er den samme) og jeg får det ventede resultat ud med
> 'Slurp'.
>
> function IsSkipAgent() {
> global $link;
>
>    $ary = array(
>       "Googlebot",
>       "Slurp",
>       "libwww-perl",
>       "msnbot",
>       "Anonymouse",
>       "MJ12bot"
>    );
>
> $res = false;
> $ip_ag = getenv("HTTP_USER_AGENT");
> while ((!$res) && list(, $value) = each($ary)) {
>    $res = ( strpos( $ip_ag, $value) !== false);
> }
>
> return $res;
> }
>
> Kan det være HTTP_USER_AGENT der snyder?

Den gemmes senere i databasen - enten som besøgende eller som blokeret,
og der står den rigtigt. Så den burde også være rigtig i strpos...
Se også svaret til Bertel...

Birger



Bertel Lund Hansen (27-08-2008)
Kommentar
Fra : Bertel Lund Hansen


Dato : 27-08-08 02:16

Birger Sørensen skrev:

> IMHO er return midt i koder, ligesom break, en uskik der gør koden
> mindre overskuelig end det er nødvendigt.

Alternativet kan være if'er i syv niveauer. Det er altså heller
ikke specielt overskueligt.

--
Bertel
http://bertel.lundhansen.dk/      FIDUSO: http://fiduso.dk/

Søg
Reklame
Statistik
Spørgsmål : 177459
Tips : 31964
Nyheder : 719565
Indlæg : 6408182
Brugere : 218881

Månedens bedste
Årets bedste
Sidste års bedste