Il browser Web più piccolo del mondo


72

backstory:

Ti piace il tuo nuovo lavoro di programmazione in una mega-multinazionale. Tuttavia, non ti è consentito navigare sul Web poiché il tuo computer ha solo una CLI. Eseguono anche sweep dei dischi rigidi di tutti i dipendenti, quindi non è possibile scaricare semplicemente un browser Web CLI di grandi dimensioni. Decidi di creare un semplice browser testuale il più piccolo possibile in modo da poterlo memorizzare e digitarlo in un file temporaneo ogni giorno.

Sfida:

Il tuo compito è quello di creare un browser Web golfed all'interno di un'interfaccia della riga di comando. Dovrebbe:

  • Prendi un singolo URL in via args o stdin
  • Dividi i componenti directorye hostdell'URL
  • Invia una semplice richiesta HTTP al hostper richiedere dettodirectory
  • Stampa il contenuto di qualsiasi tag di <p>paragrafo</p>
  • E o esci o chiedi un'altra pagina

Ulteriori informazioni:

Una semplice richiesta HTTP è simile alla seguente:

GET {{path}} HTTP/1.1
Host: {{host}}
Connection: close
\n\n

La fine delle nuove linee enfatizzate.

Una risposta tipica è simile a:

HTTP/1.1 200 OK\n
<some headers separated by newlines>
\n\n
<html>
....rest of page

Regole:

  • Deve solo funzionare sulla porta 80 (non è necessario SSL)
  • Non puoi usare netcat
  • Qualunque sia il linguaggio di programmazione utilizzato, sono consentite solo API TCP di basso livello (tranne netcat)
  • Si può non usare GUI, ricordate, è una CLI
  • Non è possibile utilizzare parser HTML, ad eccezione di quelli incorporati (BeautifulSoup non è un incorporato)
  • Bonus !! Se il programma torna indietro e richiede un altro URL invece di uscire, -40 caratteri (purché non si usi la ricorsione)
  • Nessun programma di terze parti. Ricorda, non puoi installare nulla.
  • , quindi vince il numero di byte più breve

7
Python,import webbrowser;webbrowser.open(url)
Blue

8
@muddyfish leggi le regole
TheDoctor,

4
Potete fornire una pagina web di esempio di qualche tipo per testarlo? È difficile trovare luoghi che usano <p>: P
uno spaghetto il


3
La restrizione alle interfacce socket di basso livello sembra proibire le API di livello TCP della maggior parte delle lingue che hanno API di livello TCP.
Peter Taylor,

Risposte:


63

Pure Bash (nessuna utility), 200 byte - 40 bonus = 160

while read u;do
u=${u#*//}
d=${u%%/*}
exec 3<>/dev/tcp/$d/80
echo "GET /${u#*/} HTTP/1.1
host:$d
Connection:close
">&3
mapfile -tu3 A
a=${A[@]}
a=${a#*<p>}
a=${a%</p>*}
echo "${a//<\/p>*<p>/"
"}"
done

Penso che questo dipenda dalle specifiche, anche se ovviamente stai attento all'analisi dell'HTML usando regex. Penso che l'unica cosa peggiore dell'analisi dell'HTML usando regex sia l'analisi dell'HTML usando la corrispondenza dei modelli di shell.

Questo ora riguarda lo <p>...</p>spanning su più righe. Ciascuno si <p>...</p>trova su una riga di output separata:

$ echo "http://example.com/" | ./smallbrowse.sh
This domain is established to be used for illustrative examples in documents. You may use this     domain in examples without prior coordination or asking for permission.
<a href="http://www.iana.org/domains/example">More information...</a>
$ 

35
Devi averlo memorizzato entro domani.
Conor O'Brien,

14
+ ∞ per "analizzare HTML usando la corrispondenza del modello di shell"
SztupY,

76
-1 perché il tuo avatar è un messaggio subliminale
TheDoctor,

1
... puoi effettuare connessioni TCP da Bash? Ora sono veramente terrorizzato!
MathematicalOrchid,

2
Nota: /dev/tcpè un'estensione opzionale e potrebbe non essere presente nella build di bash. Devi compilare --enable-net-redirectionsper averlo.
Chris Down,

21

PHP, 175 byte (215 - 40 bonus) 227 229 239 202 216 186 byte

Divertiti a navigare sul Web:

for(;$i=parse_url(trim(fgets(STDIN))),fwrite($f=fsockopen($h=$i[host],80),"GET $i[path] HTTP/1.1
Host:$h
Connection:Close

");preg_match_all('!<p>(.+?)</p>!si',stream_get_contents($f),$r),print join("
",$r[1])."
");

Legge URL da STDINlike http://www.example.com/. Emette i paragrafi separati da una riga " \n".


Ungolfed

for(; $i=parse_url(trim(fgets(STDIN))); ) {
    $h = $i['host'];
    $f = fsockopen($h, 80);

    fwrite($f, "GET " . $i['path'] . " HTTP/1.1\nHost:" . $h . "\nConnection:Close\n\n");

    $c = stream_get_contents($f)

    preg_match_all('!<p>(.+?)</p>!si', $c, $r);
    echo join("\n", $r[1]) . "\n";
}

Prima versione che supporta un solo URL

$i=parse_url($argv[1]);fwrite($f=fsockopen($h=$i[host],80),"GET $i[path] HTTP/1.1\nHost:$h\nConnection:Close\n\n");while(!feof($f))$c.=fgets($f);preg_match_all('!<p>(.+?)</p>!sim',$c,$r);foreach($r[1]as$p)echo"$p\n";

inserisci qui la descrizione dell'immagine


Le modifiche

  • Come sottolineato nei commenti di Braintist , ho completamente dimenticato di includere il percorso. Ora è stato risolto, grazie. Aggiunti 30 byte .
  • 3 byte salvati ripristinando $c(contiene il contenuto della pagina) con $c=$i=parse_url(trim(fgets(STDIN)));invece di $c=''.
  • 12 byte salvati sostituendoli \ncon nuove righe (5 byte), uno- whileloop con for(2 byte), inserendo quasi tutto nelle espressioni di for(2 byte) e sostituendo foreachcon join(3 byte). Grazie a Blackhole .
  • Salvato 3 byte sostituendo fgetscon stream_get_contentsGrazie a bwoebi .
  • 5 byte salvati rimuovendo la reinizializzazione in $cquanto non è più necessario $c .
  • Salvato 1 byte rimuovendo il modificatore di pattern mda Regex. Grazie a manatwork


1
@briantist Oh amico, mi sono perso del tutto. : D Grazie, ora è stato risolto.
insertusernamehere

1
Non posso sopportare che Perl batte PHP, quindi non dimenticare: whileè proibito quando si gioca a golf ( forspesso è più corto ma mai più lungo), e per fare una nuova riga, basta premere Invio (1 byte anziché 2 per \n)! Ecco il tuo codice (non testato) un po 'più golfato (227 byte), con la nuova riga sostituita da :for(;$c=$i=parse_url(trim(fgets(STDIN))),fwrite($f=fsockopen($h=$i[host],80),"GET $i[path] HTTP/1.1↵Host:$h↵Connection:Close↵↵");preg_match_all('!<p>(.+?)</p>!sim',$c,$r),print join('↵',$r[1]).'↵')for(;!feof($f);)$c.=fgets($f);
Blackhole

1
Non intendo "proibito" come "contro le regole", intendo solo che non è affatto utile, dal momento che un for-loop è sempre meglio di un while-loop;).
Blackhole,

1
@MichaelDibbets In realtà l'ho già fatto come scritto nella modifica. Hm. Fammi vedere. Haha, ho dimenticato di copiare e contare lo snippet finale. Duh : D Succedono cose del genere, se aggiorni il codice prima di colazione. Grazie per segnalarlo.
insertusernamehere

14

Perl, 132 byte

155 byte codice + 17 per -ln -MIO::Socket- 40 per chiedere continuamente gli URL

Come con la risposta di @ DigitalTrauma, regex analizza HTML, fammi sapere se non è accettabile. Non continua più ad analizzare gli URL ... Vedrò più avanti ... Comunque vicino a Bash! Grazie mille a @ Schwern per avermi salvato 59 (!) Byte e a @ skmrx per aver corretto il bug per consentire un reclamo del bonus!

m|(http://)?([^/]+)(/(\S*))?|;$s=new IO::Socket::INET"$2:80";print$s "GET /$4 HTTP/1.1
Host:$2
Connection:close

";local$/=$,;print<$s>=~m|<p>(.+?)</p>|gs

uso

$perl -ln -MIO::Socket -M5.010 wb.pl 
example.com
This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.<a href="http://www.iana.org/domains/example">More information...</a>
example.org
This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.<a href="http://www.iana.org/domains/example">More information...</a>

Ho corretto un bug e abbreviato il codice rimuovendo la necessità di dichiarare $ h e $ p o avere un percorso predefinito. Inoltre non richiede più un trailing / sull'host.
Schwern,

1
Ora siamo noi a battere. :)
Schwern,

Penso di aver finito per la notte. :)
Schwern,

Poiché lo script richiede un altro URL invece di uscire, puoi richiedere altri -40 byte
svsd

1
@DigitalTrauma hai davvero ragione! Ho richiesto il bonus grazie a skmrx che risolve il mio bug con '$ /' e non sarei vicino al tuo se non fosse per Schwern!
Dom Hastings,

13

PowerShell, 315 294 268 262 254 byte

355 334 308 302 294 - 40 per prompt

$u=[uri]$args[0]
for(){
$h=$u.Host
$s=[Net.Sockets.TcpClient]::new($h,80).GetStream()
$r=[IO.StreamReader]::new($s)
$w=[IO.StreamWriter]::new($s)
$w.Write("GET $($u.PathAndQuery) HTTP/1.1
HOST: $h

")
$w.Flush()
($r.ReadToEnd()|sls '(?s)(?<=<p>).+?(?=</p>)'-a).Matches.Value
[uri]$u=Read-Host
}

Richiede PowerShell v5

Tutte le terminazioni di riga (comprese quelle incorporate nella stringa) sono solo newline \n(grazie a Blackhole ) che è completamente supportato da PowerShell (ma se stai testando, fai attenzione; ISE usa \r\n).


4
+1 per rendere le funzioni di amministrazione del mio server molto più produttive
rispetto al

HTTP richiede CRLF, non LF! [ HTTPSYNTAX ]
Spazzolino da denti

2
@toothbrush Ha! Punto preso, ma la disposizione di tolleranza sembra avere pieno effetto. Chiaramente questa attività riguarda ciò che funziona e non ciò che è corretto (altrimenti non analizzeremo HTML con regex e utilizzeremo librerie TCP di basso livello invece di librerie esistenti ben testate).
Briantist,

1
@briantist greenbytes.de/tech/webdav/rfc7230.html#rfc.section.3.5 afferma che "un destinatario PUO 'riconoscere un singolo LF come terminatore di linea e ignorare qualsiasi CR precedente". Ho letto che significa che la maggior parte dei server Web lo implementerebbe, e la domanda sicuramente non dice che deve generare richieste corrette GET ... :)
Spazzolino da denti

8

Groovy script, 89 , 61 byte

Loop posteriore per bonus 101- 40 = 61

System.in.eachLine{l->l.toURL().text.findAll(/<p>(?s)(.*?)<\/p>/).each{println it[3..it.length()-5]}}

Con solo args, 89 byte

this.args[0].toURL().text.findAll(/<p>(?s)(.*?)<\/p>/).each{println it[3..it.length()-5]}

1
Groovy ha superato tutti. Come dovrebbe essere.
uno spaghetto il

1
@quartata Se rimarrà così, sarà la prima volta in assoluto , quindi ...;)
Geobits,

11
"Sono consentite solo API TCP di basso livello"
Digital Trauma,

Sì, sono d'accordo con @DigitalTrauma che questo non utilizza un'API TCP di basso livello. Le regole stabiliscono che devi dividere l'host e il percorso da solo.
TheDoctor

6

Bash (potrebbe essere barare ma sembra essere all'interno delle regole) 144-40 = 105

while read a;do
u=${a#*//}
d=${u%%/*}
e=www.w3.org
exec 3<>/dev/tcp/$d/80
echo "GET /services/html2txt?url=$a HTTP/1.1
Host:$d
">&3
cat <&3
done

Grazie a Digital Trauma.

Dato che non ho bisogno di dividere l'URL, funziona anche: 122-40 = 82

while read a;do
d=www.w3.org
exec 3<>/dev/tcp/$d/80
echo "GET /services/html2txt?url=$a HTTP/1.1
Host:$d
">&3   
cat <&3
done

8
Direi che l'uso di questo convertitore html2txt online è una scappatoia standard
Digital Trauma,

1
Sì. E uso anche cat, quindi la tua soluzione è sicura.
philcolbourn,

5

C 512 byte

#include <netdb.h>
int main(){char i,S[999],b[99],*p,s=socket(2,1,0),*m[]={"<p>","</p>"};long n;
gets(S);p=strchr(S,'/');*p++=0;struct sockaddr_in a={0,2,5<<12};memcpy(&a.
sin_addr,gethostbyname(S)->h_addr,4);connect(s,&a,16);send(s,b,sprintf(b,
"GET /%s HTTP/1.0\r\nHost:%s\r\nAccept:*/*\r\nConnection:close\r\n\r\n",p,S),0);
p=m[i=0];while((n=recv(s,b,98,0))>0)for(char*c=b;c<b+n;c++){while(*c==*p &&*++p)
c++;if(!*p)p=m[(i=!i)||puts("")];else{while(p>m[i]){if(i)putchar(c[m[i]-p]);p--;}
if(i)putchar(*c);}}} 

Basato vagamente sulla mia voce qui , prende l'indirizzo web senza un "https: //" iniziale. Non gestirà <p>correttamente le coppie nidificate :(

Testato ampiamente su www.w3.org/People/Berners-Lee/
Funziona quando compilato Apple LLVM version 6.1.0 (clang-602.0.53) / Target: x86_64-apple-darwin14.1.1
Ha un comportamento abbastanza indefinito che potrebbe non funzionare altrove.


Stavo scendendo all'incirca nella stessa traccia (questo segfault quando compilato con gcc), ma dovrebbe essere possibile ottenere meno di 400 byte in C. Non sono sicuro del clang, ma non dovresti dichiarare il tipo di ritorno di main. È anche possibile rimuovere l'inclusione e "accedere" alle strutture come array di numeri interi. Ho anche ricevuto risposte con "GET /% s HTTP / 1.1 \ r \ n \ r \ n \", ma il chilometraggio può variare in base al sito ...
Comintern

5

Ruby, 118

Sorgente di 147 byte; 11 byte ' -lprsocket'; -40 byte per il looping.

*_,h,p=$_.split'/',4
$_=(TCPSocket.new(h,80)<<"GET /#{p} HTTP/1.1
Host:#{h}
Connection:close

").read.gsub(/((\A|<\/p>).*?)?(<p>|\Z)/mi,'
').strip

Esempio di utilizzo:

$ ruby -lprsocket wb.rb
http://example.org/
This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.
<a href="http://www.iana.org/domains/example">More information...</a>
http://www.xkcd.com/1596/
Warning: this comic occasionally contains strong language (which may be unsuitable for children), unusual humor (which may be unsuitable for adults), and advanced mathematics (which may be unsuitable for liberal-arts majors).

This work is licensed under a
<a href="http://creativecommons.org/licenses/by-nc/2.5/">Creative Commons Attribution-NonCommercial 2.5 License</a>.


This means you're free to copy and share these comics (but not to sell them). <a rel="license" href="/license.html">More details</a>.

4

AutoIt , 347 byte

Func _($0)
$4=StringTrimLeft
$0=$4($0,7)
$3=StringSplit($0,"/")[1]
TCPStartup()
$2=TCPConnect(TCPNameToIP($3),80)
TCPSend($2,'GET /'&$4($0,StringLen($3))&' HTTP/1.1'&@LF&'Host: '&$3&@LF&'Connection: close'&@LF&@LF)
$1=''
Do
$1&=TCPRecv($2,1)
Until @extended
For $5 In StringRegExp($1,"(?s)\Q<p>\E(.*?)(?=\Q</p>\E)",3)
ConsoleWrite($5)
Next
EndFunc

analisi

Ingresso:

_('http://www.autoitscript.com')

Produzione:

You don't have permission to access /error/noindex.html
on this server.

Ingresso:

_('http://www.autoitscript.com/site')

Produzione:

The document has moved <a href="https://www.autoitscript.com/site">here</a>.

Osservazioni

  • Non supporta <p>tag nidificati
  • Supporta solo <p>tag (senza distinzione tra maiuscole e minuscole), si interromperà su ogni altro formato di tag
  • Panics Loops indefinitamente quando si verifica un errore

4

C #, 727 byte - 40 = 687 byte

using System.Text.RegularExpressions;class P{static void Main(){a:var i=System.Console.ReadLine();if(i.StartsWith("http://"))i=i.Substring(7);string p="/",h=i;var l=i.IndexOf(p);
if(l>0){h=i.Substring(0,l);p=i.Substring(l,i.Length-l);}var c=new System.Net.Sockets.TcpClient(h,80);var e=System.Text.Encoding.ASCII;var d=e.GetBytes("GET "+p+@" HTTP/1.1
Host: "+h+@"
Connection: close

");var s=c.GetStream();s.Write(d,0,d.Length);byte[]b=new byte[256],o;var m=new System.IO.MemoryStream();while(true){var r=s.Read(b,0,b.Length);if(r<=0){o=m.ToArray();break;}m.Write(b,0,r);}foreach (Match x in new Regex("<p>(.+?)</p>",RegexOptions.Singleline).Matches(e.GetString(o)))System.Console.WriteLine(x.Groups[1].Value);goto a;}}

È un po 'di allenamento ma sicuramente memorabile :)

Ecco una versione non golfata:

using System.Text.RegularExpressions;
class P
{
    static void Main()
    {
    a:
        var input = System.Console.ReadLine();
        if (input.StartsWith("http://")) input = input.Substring(7);
        string path = "/", hostname = input;
        var firstSlashIndex = input.IndexOf(path);
        if (firstSlashIndex > 0)
        {
            hostname = input.Substring(0, firstSlashIndex);
            path = input.Substring(firstSlashIndex, input.Length - firstSlashIndex);
        }
        var tcpClient = new System.Net.Sockets.TcpClient(hostname, 80);
        var asciiEncoding = System.Text.Encoding.ASCII;
        var dataToSend = asciiEncoding.GetBytes("GET " + path + @" HTTP/1.1
Host: " + hostname + @"
Connection: close

");
        var stream = tcpClient.GetStream();
        stream.Write(dataToSend, 0, dataToSend.Length);
        byte[] buff = new byte[256], output;
        var ms = new System.IO.MemoryStream();
        while (true)
        {
            var numberOfBytesRead = stream.Read(buff, 0, buff.Length);
            if (numberOfBytesRead <= 0)
            {
                output = ms.ToArray();
                break;
            }
            ms.Write(buff, 0, numberOfBytesRead);
        }
        foreach (Match match in new Regex("<p>(.+?)</p>", RegexOptions.Singleline).Matches(asciiEncoding.GetString(output)))
        {
            System.Console.WriteLine(match.Groups[1].Value);
            goto a;
        }
    }
}

Come puoi vedere, ci sono problemi di perdita di memoria come bonus :)


Dov'è la perdita di memoria? Non vedo usingdichiarazioni intorno ai flussi ma ciò non crea perdite.
Gusdor,

Puoi tagliare qualche altro byte: input = input.trimStart ("http: //") sostituirà la clausola "if" e dovresti essere in grado di usare System.Text.Encoding.ASCII.GetBytes () direttamente senza per memorizzarlo prima in asciiEncoding. Penso che saresti persino venuto fuori con un "Uso del sistema;" linea e sbarazzarsi di una manciata di "Sistema".
minnmass

3

JavaScript (NodeJS) - 187 166

s=require("net").connect(80,p=process.argv[2],_=>s.write("GET / HTTP/1.0\nHost: "+p+"\n\n")&s.on("data",d=>(d+"").replace(/<p>([^]+?)<\/p>/g,(_,g)=>console.log(g))));

187:

s=require("net").connect(80,p=process.argv[2],_=>s.write("GET / HTTP/1.1\nHost: "+p+"\nConnection: close\n\n")&s.on("data",d=>(d+"").replace(/<p>([^]+?)<\/p>/gm,(_,g)=>console.log(g))));

Uso:

node file.js www.example.com

O formattato

var url = process.argv[2];
s=require("net").connect(80, url ,_=> {
     s.write("GET / HTTP/1.1\nHost: "+url+"\nConnection: close\n\n");
     s.on("data",d=>(d+"").replace(/<p>([^]+?)<\/p>/gm,(_,g)=>console.log(g)))
});

1
Avvertenza: questo funzionerà per le piccole pagine - le pagine più grandi emettono più eventi di dati.
Benjamin Gruenbaum,

3

Python 2 - 212 209 byte

import socket,re
h,_,d=raw_input().partition('/')
s=socket.create_connection((h,80))
s.sendall('GET /%s HTTP/1.1\nHost:%s\n\n'%(d,h))
p=''
while h:h=s.recv(9);p+=h
for g in re.findall('<p>(.*?)</p>',p):print g

È possibile salvare due byte eliminando gli spazi bianchi while h:prima e dopo i due punti print g.
Skyler,

E un altro byte con 'GET /%s HTTP/1.1\nHost:%s\n\n'.
Cees Timmerman,

3

Python 2, 187-40 = 147 (141 in un REPL)

Versione compressa e in loop della risposta di Zac :

import socket,re
while 1:h,_,d=raw_input().partition('/');s=socket.create_connection((h,80));s.sendall('GET /%s HTTP/1.1\nHost:%s\n\n'%(d,h));print re.findall('<p>(.*?)</p>',s.recv(9000))

Esempio:

dictionary.com
['The document has moved <a href="http://dictionary.reference.com/">here</a>.']
dictionary.reference.com
[]
paragraph.com
[]
rare.com
[]

In realtà utile è questo:

207 - 40 = 167

import socket,re
while 1:h,_,d=raw_input().partition('/');s=socket.create_connection((h,80));s.sendall('GET /%s HTTP/1.1\nHost:%s\n\n'%(d,h));print'\n'.join(re.findall('<p>(.*?)</p>',s.recv(9000),re.DOTALL))

Esempio:

example.org
This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.
<a href="http://www.iana.org/domains/example">More information...</a>
www.iana.org/domains/example
The document has moved <a href="/domains/reserved">here</a>.
www.iana.org/domains/reserved

dictionary.com
The document has moved <a href="http://dictionary.reference.com/">here</a>.
dictionary.reference.com

catb.org

      <a href="http://validator.w3.org/check/referer"><img
          src="http://www.w3.org/Icons/valid-xhtml10"
          alt="Valid XHTML 1.0!" height="31" width="88" /></a>

This is catb.org, named after (the) Cathedral and the Bazaar. Most
of it, under directory esr, is my personal site.  In theory other
people could shelter here as well, but this has yet to occur.
catb.org/jargon
The document has moved <a href="http://www.catb.org/jargon/">here</a>.
www.catb.org/jargon/
This page indexes all the WWW resources associated with the Jargon File
and its print version, <cite>The New Hacker's Dictionary</cite>. It's as
official as anything associated with the Jargon File gets.
On 23 October 2003, the Jargon File achieved the
dubious honor of being cited in the SCO-vs.-IBM lawsuit.  See the <a
href='html/F/FUD.html'>FUD</a> entry for details.
www.catb.org/jargon/html/F/FUD.html
 Defined by Gene Amdahl after he left IBM to found his own company:
   &#8220;<span class="quote">FUD is the fear, uncertainty, and doubt that IBM sales people
   instill in the minds of potential customers who might be considering
   [Amdahl] products.</span>&#8221; The idea, of course, was to persuade them to go
   with safe IBM gear rather than with competitors' equipment.  This implicit
   coercion was traditionally accomplished by promising that Good Things would
   happen to people who stuck with IBM, but Dark Shadows loomed over the
   future of competitors' equipment or software.  See
   <a href="../I/IBM.html"><i class="glossterm">IBM</i></a>.  After 1990 the term FUD was associated
   increasingly frequently with <a href="../M/Microsoft.html"><i class="glossterm">Microsoft</i></a>, and has
   become generalized to refer to any kind of disinformation used as a
   competitive weapon.
[In 2003, SCO sued IBM in an action which, among other things,
   alleged SCO's proprietary control of <a href="../L/Linux.html"><i class="glossterm">Linux</i></a>.  The SCO
   suit rapidly became infamous for the number and magnitude of falsehoods
   alleged in SCO's filings.  In October 2003, SCO's lawyers filed a <a href="http://www.groklaw.net/article.php?story=20031024191141102" target="_top">memorandum</a>
   in which they actually had the temerity to link to the web version of
   <span class="emphasis"><em>this entry</em></span> in furtherance of their claims. Whilst we
   appreciate the compliment of being treated as an authority, we can return
   it only by observing that SCO has become a nest of liars and thieves
   compared to which IBM at its historic worst looked positively
   angelic. Any judge or law clerk reading this should surf through to
   <a href="http://www.catb.org/~esr/sco.html" target="_top">my collected resources</a> on this
   topic for the appalling details.&#8212;ESR]

1

gawk, 235 - 40 = 195 byte

{for(print"GET "substr($0,j)" HTTP/1.1\nHost:"h"\n"|&(x="/inet/tcp/0/"(h=substr($0,1,(j=index($0,"/"))-1))"/80");(x|&getline)>0;)w=w RS$0
for(;o=index(w,"<p>");w=substr(w,c))print substr(w=substr(w,o+3),1,c=index(w,"/p>")-2)
close(x)}

Abbassato, ma questa è una versione più spietata, che ha bisogno dell'indirizzo web senza http://all'inizio. E se vuoi accedere alla directory principale devi terminare l'indirizzo con a /. Inoltre i <p>tag devono essere in minuscolo.

La mia versione precedente in realtà non gestiva le linee che contenevano </p><p>correttamente. Questo è stato risolto.

Uscita per input example.com/

This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.
<a href="http://www.iana.org/domains/example">More information...</a>

Non funziona ancora con Wikipedia. Penso che il motivo sia che Wikipedia utilizza httpsper tutto. Ma non lo so.

La seguente versione è un po 'più tollerante con l'input e può gestire anche tag maiuscoli.

IGNORECASE=1{
    s=substr($0,(i=index($0,"//"))?i+2:0)
    x="/inet/tcp/0/"(h=(j=index(s,"/"))?substr(s,1,j-1):s)"/80"
    print"GET "substr(s,j)" HTTP/1.1\nHost:"h"\nConnection:close\n"|&x
    while((x|&getline)>0)w=w RS$0
    for(;o=index(w,"<p>");w=substr(w,c))
        print substr(w=substr(w,o+3),1,c=index(w,"/p>")-2)
    close(x)
}

Non sono sicuro della "Connection:close"linea. Non sembra essere obbligatorio. Non sono riuscito a trovare un esempio che avrebbe funzionato diversamente con o senza.


1

Powershell (4) 240

$input=Read-Host ""
$url=[uri]$input
$dir=$url.LocalPath
Do{
$res=Invoke-WebRequest -URI($url.Host+"/"+$dir) -Method Get
$res.ParsedHtml.getElementsByTagName('p')|foreach-object{write-host $_.innerText}
$dir=Read-Host ""
}While($dir -NE "")

Ungolfed (non è richiesto il proxy)

$system_proxyUri=Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyServer
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxyUri = $proxy.GetProxy($system_proxyUri.ProxyServer)
$input = Read-Host "Initial url"
#$input="http://stackoverflow.com/questions/tagged/powershell"
$url=[uri]$input
$dir=$url.LocalPath
Do{
$res=Invoke-WebRequest -URI($url.Host+"/"+$dir) -Method Get -Proxy($proxyUri)
$res.ParsedHtml.getElementsByTagName('p')|foreach-object{write-host $_.innerText}
$dir=Read-Host "next dir"
}While($dir -NE "")

modifica * anche non difficile da memorizzare ^^


-1

Java 620 B

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;

public class JavaApplication12 {

    public static void main(String[] args) {
        try {             
            BufferedReader i = new BufferedReader(new InputStreamReader(new URL(args[0]).openStream()));
            String l;
            boolean print = false;
            while ((l = i.readLine()) != null) {
                if (l.toLowerCase().contains("<p>")) {
                    print = true;
                }
                if (print) {
                    if (l.toLowerCase().contains("</p>")) {
                        print = false;
                    }
                    System.out.println(l);
                }
            }

        } catch (Exception e) {

        }
    }

}

2
Benvenuto in Programmazione di puzzle e codice golf! Sfortunatamente, questo invio non è valido. La domanda consente solo solo API TCP di basso livello, quindi non è possibile utilizzarle InputStreamReader.
Dennis,

1
Oh, mi dispiace tanto e grazie per averlo indicato. farà meglio nella prossima risposta
Shalika Ashan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.