webForumDet fria alternativet

Hitta siffra från Google med regular expression

15 svar · 1 670 visningar · startad av civilpolisen

civilpolisenMedlem sedan dec. 2009872 inlägg
#1

Google presenterar det totala antalet länkar i sitt index på detta viset, i koden:

Ungefär 1&nbsp;470&nbsp;000 resultat</div>

Jag bara tror att regular expressions ska vara bra till detta.
Finns det något sätt att få ut denna siffran från sökresultatet?

i2n2Medlem sedan jan. 2007177 inlägg
#2

Plocka bort alla tecken som inte är siffror.

Eftersom jag inte vet i vilken miljö du jobbar så visar jag ett exempel med sed.

$ echo "Ungefär 1&nbsp;470&nbsp;000 resultat</div>" | sed 's/[^[:digit:]]//g'

ger resultatet

1470000

civilpolisenMedlem sedan dec. 2009872 inlägg
#3

Tack för svar! Just sed är jag inte bekant med. Jag arbetar med REALbasic som är en snikvarant av VisualBasic fast med den skillnaden att kompilerad kod fungerar även på Mac och Linux.

<a href="www.hemligsida.se?mysko=klureri&swrnum=1540">Här är en länk... typ...</a>

***

  Dim myRegEx As RegEx
  Dim myMatch As RegExMatch
  Dim ResultString As String
  myRegEx = New RegEx
  myRegEx.Options.CaseSensitive = True
  myRegEx.SearchPattern = "swrnum=([\d]+)"
  myMatch = myRegEx.Search(strText)
  
  If myMatch <> Nil Then
    'TextArea1.text = myMatch.SubExpressionString(1)
    return myMatch.SubExpressionString(1)
  Else
    'ResultString = ""
    'TextArea1.text  = "no match found"
  End If

Detta är en funktion och om du skickar in första raden så returneras siffrorna.
Går denna kod att kombinera med sed?
SearchPattern = ??

Kanske jag kan klura ut detta själv...

i2n2Medlem sedan jan. 2007177 inlägg
#4

Nu är realBASIC inte mitt område men google ger.

The easy solution would be to search for everything that IS NOT a number.
Replacing those with nothing. The string left over would be your number.

Rgx.SearchPattern = "\D+"
Rgx.ReplacementPattern = ""
Rgx.Options.ReplaceAllMatches = true

Return Rgx.Replace( source )

Hämtat från: http://support.realsoftware.com/listarchives/realbasic-nug/2003-12/msg01857.html

civilpolisenMedlem sedan dec. 2009872 inlägg
#5

Tack för svar!
REALbasic använder samma bibliotek som Perl, Python och PHP.
Python Compatible Regular Expressions: http://www.pcre.org/

Du behöver inte besöka hemsidan, men kompetensen kring detta är inte begränsad till REALbasic, så att säga! :-)

  Dim myRegEx As RegEx
  Dim myMatch As RegExMatch
  Dim ResultString As String
  myRegEx = New RegEx
  myRegEx.Options.CaseSensitive = True
  'myRegEx.SearchPattern = "swrnum=([\d]+)"
  'myRegEx.SearchPattern = "([\d]+)&nbsp;([\d]+)&nbsp;([\d]+)"
  'myRegEx.SearchPattern = "([\d]+)\&\n\b\s\p;([\d]+)\&\n\b\s\p;([\d]+)"
  myRegEx.SearchPattern = "([\d]+)[&nbsp;]([\d]+)[&nbsp;]([\d]+)"
  myMatch = myRegEx.Search(strText)
  
  
  If myMatch <> Nil Then
    'TextArea1.text = myMatch.SubExpressionString(1)
    return myMatch.SubExpressionString(1)
  Else
    'ResultString = ""
    'TextArea1.text  = "no match found"
  End If

Jag har prövat lite olika varianter och det blir som bäst en etta, 1!
En vanlig sökning på Google returnerar en sträng med 54.000 tecken... En mindre novell!! Nu är ju "antalet träffar" lyckligtvis i den övre halvan av denna textmassa. Det gör proceduren aningen enklare.

voigtann1Medlem sedan juni 20019 519 inlägg
#6

nu vet jag inte hur regex bitarna fungera i REALbasic men [ ] träffar inte   utan träffar ett av tecknena &, n, s, p eller ;

([\d]+)(?:&nbsp;)?([\d]+)(?:&nbsp;)?([\d]+)

men om du nu skulle få en större träff än 1 000 000 träffar som tex 1000 000 000 000 så kommer uttrycket inte hitta något.

civilpolisenMedlem sedan dec. 2009872 inlägg
#7

Tack för svar!
Din kod fungerar inte...
Eller, det gör den kanske men det blir fel svar! Det blir 88, borde bli 1 600 000... (Konstigt, tidigare i veckan var det 1 700 000... Nåja!)

http://www.google.se/search?hl=sv&q=ghostwriter in real life

Detta är sökkriteriet jag har använt mig av, men det kan vara vilket som helst.

Just denna fråga ger mig 56.513 tecken. Det är otroligt mycket information Google tillhandahåller i ett svep!

Jag är fullt medveten om att det inte kommer fungera med andra resultat, det är helt okej.

voigtann1Medlem sedan juni 20019 519 inlägg
#8

Den hämtar ut alla nummer på resultat sidan, du måste vara mer specifik på vilket tal du vill hämta ut

nitro2k01Medlem sedan aug. 20039 342 inlägg
#9

voigtann1: För det första kommer ju ditt uttryck matcha första bästa siffra i HTML-koden. För det andra har du fel i det du säger om antalet resultat. Gränsen är inte 1 000 000 utan 999 999 999. Men det är ju bara ett misstag i det du skrev. Ett större problem med uttrycket är att det det inte kan matcha siffran om det finns färre resultat än 100 resultat eftersom uttrycket kräver minst tre siffror. (Ett tecken per ([\d]+)-grupp när (?: )? misslyckas.)

Jag skulle personligen ha löst problemet med uttrycket ([\d]+| )+ resultat
Det ger tillbaka en sträng i stil med 1 610 000 resultat

Denna kan sedan skrubbas ren från det extra skräpet med en regex i stil med \D+ som används för ersättning, med en tom ersättningssträng. För att förklara exakt vad som händer: \d (litet d) matchar ett numeriskt tecken. \D (stort D) matchar precis motsatsen, ett valfritt tecken som itne är numeriskt. Plusset gör att uttrycket kan matcha flera instanser åt gången internt, vilket förhoppningsvis gör att ersättningen körs någon nanosekund fortare. (t ex att   tas bort i ett svep istället för att ett tecken åt gången tas bort.) Slutresultatet blir detsamma i slutändan med eller utan plus i detta specifika fall.

Koden borde se ut så här, med reservation för att jag inte kan RealBasic och utgår från onlinedokumentation:

 Dim myRegEx As RegEx, myRegEx2 As RegEx
  Dim myMatch As RegExMatch
  Dim ResultString As String
  myRegEx = New RegEx
  myRegEx.SearchPattern = "([\d]+|&nbsp;)+ resultat"

  myRegEx2 = New RegEx
  ' Obs! Denna rad behövs för att få bort alla skräptecken!
  myRegEx2.Options.ReplaceAllMatches = True
  ' Matcha allt som inte är nuffror...
  myRegEx2.SearchPattern = "\D+"
  ' ... och ersätt med ingenting.
  myRegEx2.ReplacementPattern = ""

  myMatch = myRegEx.Search(strText)
  
  If myMatch <> Nil Then
    ' Obs! Nollan gör att hela uttrycket returneras, vilket är vad som önskas med detta uttryck!
    ResultString = myMatch.SubExpressionString(0)
    ' Här används uttrycl 2 för att rengöra strängen!
    ResultString = myRegEx2.replace(ResultString)
    return ResultString
  Else
    return ""
  End If
voigtann1Medlem sedan juni 20019 519 inlägg
#10

nitro2k01, det är det jag menar med uttrycket, den kommer inte kunna matchar ett vettigt resultat och är fullmedveten på att den kod jag postade kommer inte lösa problemet (din lösning är det jag kom och tänka på för 2h sen när min dotter vaknade, men är lite svårt att postar något sånt från mobilen ;) )

nitro2k01Medlem sedan aug. 20039 342 inlägg
#11

Ok. Förlåt om jag lät lite brysk. :)

civilpolisenMedlem sedan dec. 2009872 inlägg
#12

Kalas!! Det ger rätt svar!!
Jag kan liiiiite om regular expressions. (Med betoning på lite!!)
Nollan ska det vara, det var dumt av mig att inte skriva det själv.

***
Nu till nästa steg:
myRegEx.SearchPattern = "([\d]+| )+ resultat"

"resultat" får inte vara en del av sökmönstret.
Det fungerar på svenska, men det inte syftet. (Enbart syftet.) Denna kod ska inte vara bara för svenska och för svenska sökord.

Jag tänker att en siffra som presenteras på det viset 1 600 000 (1 600 000) bara finns på ETT ställe på svarssidan. En sak är om man söker på just "1600000" men det är ju inget sökord! Ingen optimerar sin sida för ett specifikt nummer...

tyskland:
sökord1, sökord2, sökord3 --- google.de
frankrike
sökord4, sökord5, sökord6 --- google.fr
ryssland
sökord7, sökord8, sökord9 --- google.ru
ukraina
sökord10, sökord11, sökord12 --- google.ua

"Resultat" kan inte vara en del av frågan: "Siffra + mellanslag + siffra + mellanslag + siffra"

***
"Vän av ordning" säger att det inte kommer att fungera med fler eller färre siffror. Det vet jag. Men det ska inte fungera under 100.000 i alla fall. Det blir:
siffra + mellanslag + siffra

Enkelt! Med kod kollar man om funcGetNum1, funcGetNum2, funcGetNum3 returnerar ett värde, i annat fall blir det inget värde. (Sökningen genererar för få sidor från index.)

nitro2k01Medlem sedan aug. 20039 342 inlägg
#13

Så länge du sniker in ett hl=sv i requesten (t ex http://www.google.com/search?hl=sv&q=webForum) så är du garanterad att sidan serveras på svenska.

Jag satt och filade på ett nytt uttryck, men när jag tänker vidare på saken är det nog snarare så att du bör kolla på Googles API i detta läge. API't låter dig söka och få tillbaka en XML-fil i ett standardiserat format. Detta är nog bättre i det långa loppet. Att försöka matcha HTML-kod med regex är en hädelse.

https://developers.google.com/custom-search/v1/overview

civilpolisenMedlem sedan dec. 2009872 inlägg
#14

Tråkigt att du ger upp.
"hl=sv" är skrivet i just denna raden. Men det ska inte vara så i framtiden, men det kan ju inte du veta!

Google har lagt ner sitt API för att leverera sökresultat för "inte så där jättelänge sedan", utan att jag kan ange specifikt när det var. (De som reggade tidigare fungerar det fortfarande för, men inga nya kommer till.)

Följande alternativ återstår:
1. Jag klurar vidare på detta själv.
2. Jag letar efter hjälp på annan plats.
3. Jag skiter helt i denna funktionen.

Världen går inte under, tack för du tog dig tid! :-)

***
Det slog mig nu, man skulle kunna använda "resultat" fast på lika språk. Då borde det fungera.

Alla sätt är bra utom de dåliga! :-)

nitro2k01Medlem sedan aug. 20039 342 inlägg
#15

Nepp, jag ger inte upp, jag säger åt dig att göra rätt. Och, nej det är det gamla API't som är nerlagt. Länken går till det nya API't som kallas "Custom Search API", som ska fungera utmärkt.

Men om du absolut vill fula dig kan du använda följande uttryck:

  myRegEx.SearchPattern = "/resultStats.*([\d,.]+|&nbsp;)+.*<nobr>/"

Det utnyttjar det faktum att strängen har följande format:

<div id=resultStats>About 268,000 results<nobr>

Alltså, ligger i en div med id resultStats och efterföljs av en nobr-tagg. I övrigt samma kod som ovan. Skyll inte på mig den dag Google ändrar sin HTML och uttrycket slutar funka. :)

civilpolisenMedlem sedan dec. 2009872 inlägg
#16

Tack för ditt engagemang!!
All heder till dig!!

Jag missade API-länken. Minus för mig.

Jag har kollat detta med API tidigare, men det är inget jag följer varje dag.
Jag har aldrig besökt den länken tidigare, trots att jag gjort viss research på området.
Jag har hela tiden kommit till en annan sida, även vid sök genom forum.
Där står nu, 100 fria sökningar per användare och dag. Jag utgår från att ett IP är en användare, eller nåt.
Det är ju snålt tilltaget redan på pappret. Jag har idag en lista på runt 200 sökord som jag kollar, och det fungerar jättebra. Majoriteten hamnar på förstasidan, någon på sidan 2 och någon finns inte alls på de första 10 sidorna. (Felstavningar.)

Då jag planerar för en mjukvara så blir det väl "jag" som får stå för fiolerna även i betalvarianten. Alternativet är att man ber användarna att registrera sig på Google för detta. Då blir det genast krångligt, så det är inget attraktivt alternativ. Som jag ser det, idag.

Alltså, ligger i en div med id resultStats och efterföljs av en nobr-tagg.

Det du skriver ovan stämmer kanske på din sökning, men är inte en del av "mitt material", så din galanta lösning faller tyvärr redan där.

***
Själva utmaningen ligger i att hitta på nåt som *alltid fungerar* oavsett vad Google, eller annan sökmotor, behagar att hitta på! :-)

Det är dit jag vill komma!! Det är utmaningen!!

Edit:
Att komma fram till en begränsning är också ett framsteg! :-)

259 ms totalt · 3 externa anrop · v20260731065814-full.86db40fa
126 ms — hämta forumlista (db)
123 ms — hämta statistik (db)
134 ms — hämta tråd, inlägg och bilagor (db)