Der kleinste Webbrowser der Welt


72

Hintergrundgeschichte:

Sie genießen Ihren neuen Programmierjob bei einem Mega-Multi-Unternehmen. Sie dürfen jedoch nicht im Internet surfen, da Ihr Computer nur über eine CLI verfügt. Sie durchsuchen auch die Festplatten aller Mitarbeiter, sodass Sie nicht einfach einen großen CLI-Webbrowser herunterladen können. Sie entscheiden sich für einen einfachen Textbrowser, der so klein wie möglich ist, damit Sie ihn sich merken und jeden Tag in eine temporäre Datei eingeben können.

Herausforderung:

Ihre Aufgabe ist es, einen Golf-Webbrowser innerhalb einer Befehlszeilenschnittstelle zu erstellen. Es sollte:

  • Nehmen Sie eine einzelne URL über args oder stdin ein
  • Teilen Sie die directoryund hostKomponenten der URL
  • Senden Sie eine einfache HTTP-Anfrage an die, hostum diese anzuforderndirectory
  • Drucken Sie die Inhalte der <p>Absatz - </p>Tags
  • Und entweder beenden oder nach einer anderen Seite fragen

Mehr Info:

Eine einfache HTTP-Anfrage sieht folgendermaßen aus:

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

Letzte Zeilenumbrüche werden hervorgehoben.

Eine typische Antwort sieht wie folgt aus:

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

Regeln:

  • Es muss nur auf Port 80 funktionieren (kein SSL erforderlich)
  • Sie dürfen netcat nicht verwenden
  • Unabhängig von der verwendeten Programmiersprache sind nur TCP-APIs auf niedriger Ebene zulässig (außer Netcat).
  • Sie können die GUI möglicherweise nicht verwenden, denken Sie daran, es ist eine CLI
  • Sie dürfen keine HTML-Parser verwenden, außer eingebauten (BeautifulSoup ist kein eingebauter Parser).
  • Bonus!! Wenn Ihr Programm eine Schleife durchläuft und nach einer anderen URL fragt, anstatt zu beenden, -40 Zeichen (solange Sie keine Rekursion verwenden)
  • Keine Programme von Drittanbietern. Denken Sie daran, Sie können nichts installieren.
  • , so dass die kürzeste Anzahl von Bytes gewinnt

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

8
@ Schlammfisch lesen Sie die Regeln
TheDoctor

4
Können Sie eine Beispiel-Webseite bereitstellen, um dies zu testen? Es ist schwierig Orte zu finden, die <p>: P
a spaghetto


3
Die Beschränkung auf Low-Level-Socket-Schnittstellen scheint die TCP-Level-APIs der meisten Sprachen mit TCP-Level-APIs zu verbieten.
Peter Taylor

Antworten:


63

Pure Bash (keine Dienstprogramme), 200 Bytes - 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

Ich denke, dass dies der Spezifikation entspricht, aber achten Sie natürlich auf das Parsen von HTML mit Regex. Ich denke, das Einzige, was schlimmer ist als das Parsen von HTML mit Regex, ist das Parsen von HTML mit Shell-Pattern-Matching.

Dies betrifft nun das <p>...</p>Überspannen mehrerer Zeilen. Jedes <p>...</p>steht in einer separaten Ausgabezeile:

$ 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
Sie müssen dies bis morgen auswendig lernen.
Conor O'Brien

14
+ ∞ für "Parsen von HTML mit Shell-Pattern-Matching"
SztupY

76
-1, weil Ihr Avatar unterschwellige
Botschaften

1
... Sie von Bash aus TCP-Verbindungen herstellen können? Jetzt habe ich wirklich Angst!
MathematicalOrchid

2
Hinweis: Dies /dev/tcpist eine optionale Erweiterung und möglicherweise nicht in Ihrem Bash-Build enthalten. Sie müssen mit kompilieren --enable-net-redirections, um es zu haben.
Chris Down

21

PHP, 175 Bytes (215 - 40 Bonus) 227 229 239 202 216 186 Bytes

Viel Spaß beim Stöbern im Internet:

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])."
");

Liest URLs von STDINlike http://www.example.com/. Gibt durch " \n" getrennte Absätze aus .


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";
}

Erste Version, die nur eine URL unterstützt

$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";

Bildbeschreibung hier eingeben


Bearbeitungen

  • Wie in den Kommentaren von Braintist erwähnt , habe ich völlig vergessen, den Pfad anzugeben . Das ist jetzt behoben, danke. 30 Bytes hinzugefügt .
  • 3 Bytes gespart durch Zurücksetzen $c(enthält den Seiteninhalt) mit $c=$i=parse_url(trim(fgets(STDIN)));anstelle von $c=''.
  • Gespeicherte 12 Bytes durch Ersetzen \nmit neuen Leitungen (5 Bytes), eine while-loop mit for(2 Bytes), Platzieren fast alles in die Ausdrücke von for(2 Byte) und durch Ersetzen foreachmit join(3 Bytes). Danke an Blackhole .
  • 3 Bytes gespart durch Ersetzen fgetsdurch stream_get_contentsDanke an bwoebi .
  • 5 Bytes gespart, indem die Neuinitialisierung von entfernt wurde, $cda sie überhaupt nicht mehr benötigt wird $c .
  • Gespeichert 1 Byte durch das Muster Modifikator Entfernen mvon der Regex. Dank der Handarbeit


1
@briantist Oh man, das habe ich total vermisst. : D Danke, es ist jetzt behoben.
insertusernamehere

1
Ich kann es nicht ertragen, dass Perl PHP schlägt. Vergessen Sie also nicht, dass Perl whilebeim Golfen verboten ist ( foroft kürzer, aber nie länger). Um eine neue Zeile zu erstellen, drücken Sie einfach die Eingabetaste (1 Byte statt 2 für \n). Hier ist Ihr (ungetesteter) Code ein bisschen besser (227 Bytes), wobei die neue Zeile ersetzt wird durch :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
Ich meine nicht "verboten" als "gegen die Regeln", ich meine nur, dass das überhaupt nicht nützlich ist, da ein for-loop immer besser ist als ein while-loop;).
Blackhole

1
@MichaelDibbets Eigentlich habe ich das schon so gemacht wie im Edit geschrieben. Hm. Lass mich sehen. Haha, ich habe vergessen, das letzte Snippet zu kopieren und zu zählen. Duh : D Solche Dinge passieren, wenn Sie Ihren Code vor dem Frühstück aktualisieren. Vielen Dank für den Hinweis.
insertusernamehere

14

Perl, 132 Bytes

155 Byte Code + 17 für -ln -MIO::Socket- 40 für die ständige Abfrage von URLs

Wie bei der Antwort von @DigitalTrauma, bei der regulären Syntaxanalyse von HTML, lassen Sie mich wissen, ob dies nicht akzeptabel ist. Parset keine URLs mehr ... Ich schaue mir das später an ... In der Nähe von Bash! Ein großes Dankeschön an @ Schwern für das Speichern von 59 (!) Bytes und an @ skmrx für das Beheben des Fehlers, um einen Anspruch auf den Bonus zu erheben!

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

Verwendungszweck

$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>

Ich habe einen Fehler behoben und den Code verkürzt, indem ich die Notwendigkeit beseitigt habe, $ h und $ p zu deklarieren oder einen Standardpfad zu verwenden. Es ist auch kein Trailing / mehr auf dem Host erforderlich.
Schwern

1
Wir sind derjenige, den es jetzt zu schlagen gilt. :)
Schwern

Ich glaube, ich bin für die Nacht fertig. :)
Schwern

Da das Skript nach einer anderen URL fragt, anstatt sie zu beenden, können Sie zusätzliche -40 Bytes
anfordern

1
@DigitalTrauma du bist ja richtig! Ich habe den Bonus erhalten, weil skmrx meinen Fehler mit '$ /' behoben hat und ich ohne Schwern nicht in deiner Nähe wäre!
Dom Hastings

13

PowerShell, 315 294 268 262 254 Byte

355 334 308 302 294 - 40 zur Bestätigung

$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
}

Benötigt PowerShell v5

Alle Zeilenenden (einschließlich der in die Zeichenfolge eingebetteten) sind nur Zeilenumbrüche \n(danke Blackhole ), die von PowerShell voll unterstützt werden (aber wenn Sie testen, seien Sie vorsichtig, ISE verwendet \r\n).


4
+1, damit meine Serveradministrationsaufgaben viel produktiver erscheinen
bis zum

HTTP benötigt CRLF, nicht LF! [ HTTPSYNTAX ]
Zahnbürste

2
@ Zahnbürste Ha! Erwähnt, aber die Toleranzbestimmung scheint in vollem Umfang wirksam zu sein. Bei dieser Aufgabe geht es eindeutig darum, was funktioniert und was nicht. (Andernfalls würden wir HTML nicht mit regulären Ausdrücken analysieren und TCP-Bibliotheken auf niedriger Ebene anstelle von bereits getesteten Bibliotheken verwenden.)
Briantist

1
Laut @briantist greenbytes.de/tech/webdav/rfc7230.html#rfc.section.3.5 " KANN ein Empfänger ein einzelnes LF als Zeilenabschluss erkennen und alle vorhergehenden CR ignorieren". Ich habe gelesen, dass die meisten Webserver dies implementieren würden, und die Frage besagt definitiv nicht, dass korrekte GET Anfragen generiert werden müssen … :)
Zahnbürste

8

Grooviges Skript, 89 , 61 Bytes

Loopback für Bonus - 101- 40 = 61

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

Mit nur Argumenten, 89 Bytes

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

1
Groovy hat alle überrumpelt. So wie es sein sollte.
ein Spaghetto

1
@quartata Wenn es so bleibt, wird es das erste Mal sein , also ...;)
Geobits

11
"Nur Low-Level-TCP-APIs sind zulässig"
Digital Trauma

Ja, ich bin mit @DigitalTrauma einverstanden, dass dies keine Low-Level-TCP-API verwendet. Die Regeln besagen, dass Sie den Host und den Pfad selbst aufteilen müssen.
TheDoctor

6

Bash (könnte betrügen, scheint aber innerhalb der Regeln zu liegen) 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

Dank Digital Trauma.

Da ich die URL nicht teilen muss, funktioniert dies auch: 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
Ich würde argumentieren, dass die Verwendung dieses Online-HTML2TXT-Konverters eine Standardlücke ist
Digital Trauma

1
Ja. Und ich benutze auch Katze, damit Ihre Lösung sicher ist.
Philcolbourn

5

C 512 Bytes

#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);}}} 

Basierend lose auf meinem Eintrag hier , nimmt es die Webadresse ohne ein führendes "https: //". Verschachtelte <p>Paare werden nicht korrekt verarbeitet :(

Ausführlich getestet, www.w3.org/People/Berners-Lee/
funktioniert es, wenn es mit Apple LLVM version 6.1.0 (clang-602.0.53) / Target: x86_64-apple-darwin14.1.1
Es kompiliert wurde. Es hat genug undefiniertes Verhalten, dass es möglicherweise nirgendwo anders funktioniert.


Ich bin ungefähr den gleichen Weg gegangen (dieser Fehler tritt beim Kompilieren mit gcc auf), aber es sollte möglich sein, unter 400 Bytes in C zu kommen. Ich bin mir nicht sicher, was das Klirren betrifft, aber Sie sollten den Rückgabetyp von main nicht deklarieren müssen. Sie können stattdessen auch das Include entfernen und auf die Strukturen als Integer-Arrays zugreifen. Ich habe auch Antworten mit "GET /% s HTTP / 1.1 \ r \ n \ r \ n \" erhalten, aber die Laufleistung kann je nach Site variieren ...
Comintern

5

Rubin, 118

147-Byte-Quelle; 11 Bytes ' -lprsocket'; -40 Bytes zum Schleifen.

*_,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

Anwendungsbeispiel:

$ 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 Bytes

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

Testen

Eingang:

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

Ausgabe:

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

Eingang:

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

Ausgabe:

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

Bemerkungen

  • Unterstützt keine verschachtelten <p>Tags
  • Unterstützt nur <p>Tags (ohne Berücksichtigung der Groß- und Kleinschreibung), unterbricht jedes andere Tag-Format
  • Panics Loops auf unbestimmte Zeit, wenn ein Fehler auftritt

4

C #, 727 Bytes - 40 = 687 Bytes

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;}}

Es ist ein bisschen Training, aber sicherlich unvergesslich :)

Hier ist eine ungolfed Version:

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;
        }
    }
}

Wie Sie sehen können, gibt es Probleme mit Speicherverlusten als Bonus :)


Wo ist das Speicherleck? Ich sehe keine usingAussagen um Streams, aber das macht kein Leck.
Gusdor

Sie können einige weitere Bytes kürzen: input = input.trimStart ("http: //") ersetzt die "if" -Klausel, und Sie sollten in der Lage sein, System.Text.Encoding.ASCII.GetBytes () direkt zu verwenden, ohne dies zu müssen um es zuerst in ASCII-Codierung zu speichern. Ich denke, Sie würden sogar ein "Using System" hervorbringen. Linie und eine Handvoll "System" loswerden. s.
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))));

Verwendungszweck:

node file.js www.example.com

Oder formatiert

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
Vorsichtsmaßnahme: Dies funktioniert für kleine Seiten - größere Seiten geben mehrere Datenereignisse aus.
Benjamin Gruenbaum

3

Python 2 - 212 209 Bytes

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

Sie können zwei Bytes sparen, indem Sie das Leerzeichen nach while h:und vor dem Doppelpunkt entfernen print g.
Skyler

Und noch ein Byte mit 'GET /%s HTTP/1.1\nHost:%s\n\n'.
Cees Timmerman

3

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

Komprimierte und geloopte Version von Zacs Antwort :

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))

Beispiel:

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

Eigentlich nützlich ist das:

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))

Beispiel:

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 Bytes

{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)}

Golfen Sie es runter, aber dies ist eine unerbittlichere Version, die die Webadresse ohne http://am Anfang benötigt. Und wenn Sie auf das Stammverzeichnis zugreifen möchten, müssen Sie die Adresse mit einem abschließen /. Außerdem müssen die <p>Tags in Kleinbuchstaben geschrieben werden.

Meine frühere Version behandelte Zeilen, die </p><p>richtig enthielten , nicht. Dies ist jetzt behoben.

Ausgabe für Eingabe 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>

Funktioniert immer noch nicht mit Wikipedia. Ich denke, der Grund ist, dass Wikipedia httpsfür alles verwendet. Aber ich weiß es nicht.

In der folgenden Version ist die Eingabe etwas fehlerverzeihender und es können auch Tags in Großbuchstaben verarbeitet werden.

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)
}

Ich bin mir nicht sicher über die "Connection:close"Linie. Scheint nicht obligatorisch zu sein. Ich konnte kein Beispiel finden, das anders mit oder ohne funktionieren würde.


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 (Proxy ist nicht erforderlich)

$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 "")

edit * auch nicht zu schwer zu merken ^^


-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
Willkommen bei Programming Puzzles & Code Golf! Diese Einsendung ist leider ungültig. Die Frage lässt nur TCP-APIs auf niedriger Ebene zu, sodass Sie sie nicht verwenden können InputStreamReader.
Dennis

1
Oh, es tut mir so leid und ich danke Ihnen, dass Sie darauf hingewiesen haben. wird es in der nächsten Antwort besser machen
Shalika Ashan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.