Vinnaren i pepparkakshustävlingen!
  • 1
  • 2
2020-12-05, 22:09
  #13
Medlem
Trollfeeders avatar
Citat:
Ursprungligen postat av distans
Ja, om man pratar regexp flytande

Denna kanske kan vara till hjälp?!

https://stackoverflow.com/questions/...data-from-html

Ah, jag läste trådstarten slarvigt, trodde TS ville ha hela raden. Då ska det in lite awk eller sed i grep-uttrycket också. Men det är rätt lätt att googla fram hur man gör.
Citera
2020-12-06, 08:09
  #14
Medlem
Citat:
Ursprungligen postat av ath0
Kod:
preg_match('/<span class="hittamig">(.*?)<\/span>/s'$results$matches);
if(
count($matches) >= 2) {
    
$result $matches[1];
    
$numeric preg_replace("/[^0-9]/"""$result);
    echo 
"Original match: " $result."\r\n";
    echo 
"Numerically parsed match: " $numeric."\r\n";


Ovanstående producerar följande resultat.

Låter ju för bra, men är jag för trött nu tro?

Kod:
Warning: Undefined variable $results in curl.php on line 122

122:preg_match('/<span class="hittamig">(.*?)<\/span>/s', $results, $matches); 

Kod:
preg_match('/<span class="hittamig">(.*?)<\/span>/s'$results$matches); 
if(
count($matches) >= 2) { 
    
$result $matches[1]; 
    
$numeric preg_replace("/[^0-9]/"""$result); 
    echo 
"Original match: " $result."\r\n"
    echo 
"Numerically parsed match: " $numeric."\r\n"

__________________
Senast redigerad av matematikern88 2020-12-06 kl. 08:14.
Citera
2020-12-06, 12:33
  #15
Medlem
SKetchers avatar
Citat:
Ursprungligen postat av matematikern88
Låter ju för bra, men är jag för trött nu tro?

Hej, du är nästan där. Men du använder regex på ett icke optimalt sätt.
Istället för att regexa hela sidan "<html>3ta3546354....mkht13tyjyjkyjkeafa asmycket text som vi inte behöver söka igenom[...........] <span>5 bilar</span><html>", vilket kan bli onödigt snurrigt, så väljer vi ut Dom-noden <span> som du vill ha.

Därifrån konvertrar vi stringvärdet "5 bilar" till en siffra -> 5

Jag grävde fram en bit gammal kod från mitt bibliotek.
Kod:
// Min lokala server
$targetSite "http://127.0.0.1:5500/index2.html";
// Hämtar data genom ett Curlrequest
$dom XpathFromUrl($targetSite);

// Vi söker igenom HTML-document med Xpath istället
// Alla <span> med klassen "hittamig" tas ut och loopas
foreach ($dom->query('//span[@class="hittamig"]') as $tag) {
    
$str $tag->nodeValue// 5 bilar
    // Vi komnvertar stringen '5 bilar' till en int genom att ta bort allting som är icke-numeriskt ![0-9]
    
$str preg_replace('~\D~'''$str);
    echo 
$str;
}

/**
 * Get request to address
 */
function CurlRequest($url)
{
    
$curl curl_init();
    
curl_setopt($curlCURLOPT_URL$url);
    
curl_setopt($curlCURLOPT_HTTPHEADER, array(
        
"Rofl-Copter: haha. look at me, i'm a header",
        
"User-Agent: {Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)}",
        
"Accept-Language: {en-us,en;q=0.5}"
    
));
    
curl_setopt($curlCURLOPT_HEADER1);
    
curl_setopt($curlCURLOPT_RETURNTRANSFER1);
    
$result curl_exec($curl);
    
$info curl_getinfo($curl);
    
curl_close($curl);
    return 
$result;
}

/**
 * Convert DOMDocument -into-> DOMXPath
 */
function XpathFromUrl($url)
{
    
//$res = file_get_contents($url);
    
$res CurlRequest($url);
    
libxml_use_internal_errors(true);
    
$domdoc  = new DOMDocument();
    
$domdoc->loadHTML($res);
    
$dom = new DOMXPath($domdoc);
    return 
$dom;


Kod:
$targetSite 
Är adressen där html ligger, exempelvis "https://www.flashback.org".
Då jag inte vet hur du gör själva requesten med Curl kan du gärna använda mina två funktioner.
__________________
Senast redigerad av SKetcher 2020-12-06 kl. 12:38.
Citera
2020-12-06, 17:06
  #16
Medlem
Citat:
Ursprungligen postat av SKetcher
Hej, du är nästan där. Men du använder regex på ett icke optimalt sätt.
Istället för att regexa hela sidan "<html>3ta3546354....mkht13tyjyjkyjkeafa asmycket text som vi inte behöver söka igenom[...........] <span>5 bilar</span><html>", vilket kan bli onödigt snurrigt, så väljer vi ut Dom-noden <span> som du vill ha.

Därifrån konvertrar vi stringvärdet "5 bilar" till en siffra -> 5

Jag grävde fram en bit gammal kod från mitt bibliotek.
Kod:
// Min lokala server
$targetSite "http://127.0.0.1:5500/index2.html";
// Hämtar data genom ett Curlrequest
$dom XpathFromUrl($targetSite);

// Vi söker igenom HTML-document med Xpath istället
// Alla <span> med klassen "hittamig" tas ut och loopas
foreach ($dom->query('//span[@class="hittamig"]') as $tag) {
    
$str $tag->nodeValue// 5 bilar
    // Vi komnvertar stringen '5 bilar' till en int genom att ta bort allting som är icke-numeriskt ![0-9]
    
$str preg_replace('~\D~'''$str);
    echo 
$str;
}

/**
 * Get request to address
 */
function CurlRequest($url)
{
    
$curl curl_init();
    
curl_setopt($curlCURLOPT_URL$url);
    
curl_setopt($curlCURLOPT_HTTPHEADER, array(
        
"Rofl-Copter: haha. look at me, i'm a header",
        
"User-Agent: {Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)}",
        
"Accept-Language: {en-us,en;q=0.5}"
    
));
    
curl_setopt($curlCURLOPT_HEADER1);
    
curl_setopt($curlCURLOPT_RETURNTRANSFER1);
    
$result curl_exec($curl);
    
$info curl_getinfo($curl);
    
curl_close($curl);
    return 
$result;
}

/**
 * Convert DOMDocument -into-> DOMXPath
 */
function XpathFromUrl($url)
{
    
//$res = file_get_contents($url);
    
$res CurlRequest($url);
    
libxml_use_internal_errors(true);
    
$domdoc  = new DOMDocument();
    
$domdoc->loadHTML($res);
    
$dom = new DOMXPath($domdoc);
    return 
$dom;


Kod:
$targetSite 
Är adressen där html ligger, exempelvis "https://www.flashback.org".
Då jag inte vet hur du gör själva requesten med Curl kan du gärna använda mina två funktioner.

Fick bara ut en blank sida av din kod när jag la den i en ny fil. Testade att mixtra lite, men fick inte till det. Så här ser min kod ut. Den ligger in på min hemsida nu som test.
Sen plockar den ut all html i $result;.
Och där vill jag hitta min 5a (<span class="hittamig">)

Kod:
$data = array(
    
"email_signin" => "mail@.nu",
    
"password_signin" => "OLLE",
    
"login" => "submit"
);

$ch curl_init("http://www.URL.se/index.php");
curl_setopt($chCURLOPT_FOLLOWLOCATIONtrue);
curl_setopt($chCURLOPT_POSTtrue);
curl_setopt($chCURLOPT_POSTFIELDS$data);
curl_setopt($chCURLOPT_COOKIEJAR'cookie.txt');
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);

$result curl_exec($ch);
curl_close($ch);
echo 
$result



EDIT: Ditt fungerade klockrent! Men hur gör jag om jag behöver logga in först? Det är på sidan efter inloggningen <span "hittamig"> ligger. Tusen tack för du hjälpt mig så här långt!
__________________
Senast redigerad av matematikern88 2020-12-06 kl. 17:17.
Citera
2020-12-06, 22:20
  #17
Medlem
SKetchers avatar
Citat:
Ursprungligen postat av matematikern88
EDIT: Ditt fungerade klockrent! Men hur gör jag om jag behöver logga in först? Det är på sidan efter inloggningen <span "hittamig"> ligger. Tusen tack för du hjälpt mig så här långt!
Najs, snyggt jobbat. Jag glömde nämna att curl-request antagligen inte funkar på lokala filer. Jag hade en server igång.

Här kommer vi in på nätverk. För att räknas som "inloggad" på en hemsida kräver det att webbläsaren sparar en cookie eller liknande.

En vanlig inloggning brukar vara ungefär så här;
1. Du skickar ett inloggningsanrop ->
2. Servern svarar med en cookie ->
3. Webbläsaren sparar cookie och följer hemsidans redirekt ->
4. Hemsidan läser din cookie och sparkar ut dig om du är någonstans där du inte ska vara

Problemet är att vi inte kan klicka på en knapp när vi gör ett sådant här GET-request, istället behöver man veta adressen som punkt 1-2 skickar till. Om det är din egen hemsida lär du noga redan veta (typ hemsida.se/POST.php eller nåt), annars kan du öppna Devtools och aktivera network-tabben för att set var din info skickas till efter att du klickat login.

Så med den information kan du härma detta i ett curl POST-request typ->
Kod:
$data = ['username' => 'admin''password' => '12345'];
curl_setopt($chCURLOPT_POSTFIELDS$data); 

Och datan som kommer tillbaka innehåller förhoppningsvis något du kan använda
Kod:
$returnDataSomething curl_exe yada yada
// Cookiedata spara någonstans 

Så med andra är det egentligen två skript;
  1. Logga in och få tillbaka cookie-data som sparas
  2. Ladda cookiedata och gå direkt till vilken sida du vill

Om jag har tid nästa vecka, kan jag eventuellt göra ett login-exempel med flashback.org istället.
__________________
Senast redigerad av SKetcher 2020-12-06 kl. 22:34.
Citera
2020-12-07, 00:01
  #18
Medlem
Citat:
Ursprungligen postat av matematikern88
Låter ju för bra, men är jag för trött nu tro?

Kod:
Warning: Undefined variable $results in curl.php on line 122

122:preg_match('/<span class="hittamig">(.*?)<\/span>/s', $results, $matches); 

Kod:
preg_match('/<span class="hittamig">(.*?)<\/span>/s'$results$matches); 
if(
count($matches) >= 2) { 
    
$result $matches[1]; 
    
$numeric preg_replace("/[^0-9]/"""$result); 
    echo 
"Original match: " $result."\r\n"
    echo 
"Numerically parsed match: " $numeric."\r\n"

$results är ju såklart variabeln som innehåller ditt resultat från curl-anropet.
Tror själv du använde den variabeln i ditt originalinlägg.

Koden fungerar som du tänker sig, ska du hämta någonting bakom inlogg behöver du först spara ned cookies och återanvända dessa i anropet när du hämtar sidan igen.

Edit: i ditt fall bör den heta $result.
__________________
Senast redigerad av ath0 2020-12-07 kl. 00:18.
Citera
2020-12-07, 00:17
  #19
Medlem
Citat:
Ursprungligen postat av SKetcher
Hej, du är nästan där. Men du använder regex på ett icke optimalt sätt.
Istället för att regexa hela sidan "<html>3ta3546354....mkht13tyjyjkyjkeafa asmycket text som vi inte behöver söka igenom[...........] <span>5 bilar</span><html>", vilket kan bli onödigt snurrigt, så väljer vi ut Dom-noden <span> som du vill ha.

Du mikro-optimerar om du tror att regex är slött på den HTML-koden som tillhandahölls i TS.
Benchmarka gärna men jag tror inte direkt du vinner nåt på att loopa igenom alla element och därefter köra regex.
Utöver det får du en mer läsbar kod skulle jag vilja säga.
Citera
2020-12-07, 05:06
  #20
Medlem
Citat:
Ursprungligen postat av SKetcher
Najs, snyggt jobbat. Jag glömde nämna att curl-request antagligen inte funkar på lokala filer. Jag hade en server igång.

Här kommer vi in på nätverk. För att räknas som "inloggad" på en hemsida kräver det att webbläsaren sparar en cookie eller liknande.

En vanlig inloggning brukar vara ungefär så här;
1. Du skickar ett inloggningsanrop ->
2. Servern svarar med en cookie ->
3. Webbläsaren sparar cookie och följer hemsidans redirekt ->
4. Hemsidan läser din cookie och sparkar ut dig om du är någonstans där du inte ska vara

Problemet är att vi inte kan klicka på en knapp när vi gör ett sådant här GET-request, istället behöver man veta adressen som punkt 1-2 skickar till. Om det är din egen hemsida lär du noga redan veta (typ hemsida.se/POST.php eller nåt), annars kan du öppna Devtools och aktivera network-tabben för att set var din info skickas till efter att du klickat login.

Så med den information kan du härma detta i ett curl POST-request typ->
Kod:
$data = ['username' => 'admin''password' => '12345'];
curl_setopt($chCURLOPT_POSTFIELDS$data); 

Och datan som kommer tillbaka innehåller förhoppningsvis något du kan använda
Kod:
$returnDataSomething curl_exe yada yada
// Cookiedata spara någonstans 

Så med andra är det egentligen två skript;
  1. Logga in och få tillbaka cookie-data som sparas
  2. Ladda cookiedata och gå direkt till vilken sida du vill

Om jag har tid nästa vecka, kan jag eventuellt göra ett login-exempel med flashback.org istället.

Jag skulle vilja komma i kontakt med dig på e-post. Jag får inte skicka PM till dig (har under 50-forum inlägg.) Du har inte lust att dra ett e-post till mig? Så ska jag berätta mer.
Citera
2020-12-07, 15:32
  #21
Medlem
SKetchers avatar
Citat:
Ursprungligen postat av ath0
Du mikro-optimerar om du tror att regex är slött på den HTML-koden som tillhandahölls i TS.
Benchmarka gärna men jag tror inte direkt du vinner nåt på att loopa igenom alla element och därefter köra regex.
Utöver det får du en mer läsbar kod skulle jag vilja säga.
Det har du rätt i, att html-biten är alldeles för kort för att det ska spela någon roll i performance.

Men. Det är en enorm anti-pattern att parsa HTML med regex. Alla moderna programmeringsspråk har fullständiga verktyg för just det här syften, att bläddra i DOM-trädet. En lista med objekt är så mycket mer hanterbart än en enorm string.

Det som regexas i min kodsnutt är enbart värdet från DOM-noden för att parsa en string till int, har ingenting med sökande att göra.
Citera
  • 1
  • 2

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback