Le plus petit navigateur Web au monde


72

Histoire de fond:

Vous aimez votre nouveau poste de programmeur dans une méga-multinationale. Cependant, vous n'êtes pas autorisé à naviguer sur le Web car votre ordinateur ne dispose que d'une interface de ligne de commande. Ils effectuent également des balayages sur les disques durs de tous les employés. Vous ne pouvez donc pas simplement télécharger un navigateur Web de grande taille. Vous décidez de créer un simple navigateur textuel aussi petit que possible afin de pouvoir le mémoriser et le saisir dans un fichier temporaire tous les jours.

Défi:

Votre tâche consiste à créer un navigateur Web avec golf dans une interface de ligne de commande. Cela devrait:

  • Prendre une seule URL dans via args ou stdin
  • Fractionner les composants directoryet hostde l'URL
  • Envoyer une simple requête HTTP à la hostpour demander laditedirectory
  • Imprimer le contenu de toutes les étiquettes de <p>paragraphe</p>
  • Et soit sortir ou demander une autre page

Plus d'informations:

Une simple requête HTTP ressemble à ceci:

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

Terminer les nouvelles lignes soulignées.

Une réponse typique ressemble à:

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

Règles:

  • Il ne doit fonctionner que sur le port 80 (pas de SSL nécessaire)
  • Vous ne pouvez pas utiliser netcat
  • Quel que soit le langage de programmation utilisé, seules les API TCP de bas niveau sont autorisées (sauf netcat).
  • Vous ne pouvez pas utiliser l'interface graphique, rappelez-vous, c'est une CLI
  • Vous ne pouvez pas utiliser les analyseurs HTML, sauf ceux qui sont intégrés (BeautifulSoup n'est pas intégré)
  • Prime!! Si votre programme effectue une boucle et demande une autre URL au lieu de quitter, -40 caractères (tant que vous n'utilisez pas de récursivité)
  • Aucun programme tiers. Rappelez-vous, vous ne pouvez rien installer.
  • , donc le nombre d'octets le plus court gagne

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

8
@muddyfish lire les règles
TheDoctor

4
Pouvez-vous fournir un exemple de page Web pour le tester? Il est difficile de trouver des endroits qui utilisent <p>: P
un spaghetto

52
Sommes-nous autorisés à analyser HTML en utilisant regex ? ;-)
Digital Trauma

3
La restriction aux interfaces de socket de bas niveau semble interdire les API de niveau TCP de la plupart des langages disposant d'API de niveau TCP.
Peter Taylor

Réponses:


63

Pure Bash (sans utilitaire), 200 octets - 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

Je pense que cela dépend de la spécification, bien que bien sûr, attention à l' analyse HTML à l'aide de regex Je pense que la seule chose pire que l'analyse de HTML à l'aide de regex est l'analyse HTML à l'aide de la correspondance de modèle de shell.

Cela concerne maintenant l’ <p>...</p>étendue de plusieurs lignes. Chacun <p>...</p>est sur une ligne de sortie séparée:

$ 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
Vous devez avoir ceci mémorisé par demain.
Conor O'Brien

14
+ ∞ pour "l'analyse HTML à l'aide de la correspondance de modèle de shell"
SztupY

76
-1 parce que votre avatar est un message subliminal
TheDoctor

1
... vous pouvez établir des connexions TCP à partir de Bash? Maintenant je suis vraiment terrifié!
MathematicalOrchid

2
Remarque: cette /dev/tcpextension est facultative et peut ne pas figurer dans votre version de bash. Vous devez compiler avec --enable-net-redirectionspour l'avoir.
Chris Down

21

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

Amusez-vous à naviguer sur le 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])."
");

Lit les URL de STDINcomme http://www.example.com/. Affiche les paragraphes séparés par une nouvelle ligne " \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";
}

Première version supportant une seule 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";

entrez la description de l'image ici


Édite

  • Comme souligné dans les commentaires de Braintist , j'ai totalement oublié d'inclure le chemin. C'est corrigé maintenant, merci. Ajout de 30 octets .
  • 3 octets enregistrés en réinitialisant $c(contient le contenu de la page) avec $c=$i=parse_url(trim(fgets(STDIN)));au lieu de $c=''.
  • 12 octets enregistrés en les remplaçant \npar de nouvelles lignes (5 octets), une whileboucle avec for(2 octets), en plaçant presque tout dans les expressions de for(2 octets) et en les remplaçant foreachpar join(3 octets). Merci à Blackhole .
  • Sauvegardé 3 octets en remplaçant fgetspar stream_get_contentsMerci à bwoebi .
  • Vous avez enregistré 5 octets en supprimant la réinitialisation, $ccar vous n'en avez plus besoin $c .
  • Enregistré 1 octet en supprimant le modificateur mde motif de la regex. Merci à manatwork


1
@briantist Oh mec, ça m'a totalement manqué. : D Merci, c'est corrigé maintenant.
insertusernamehere

1
Je ne peux pas supporter que Perl bat PHP, alors n'oubliez pas: il whileest interdit de jouer au golf ( forsouvent plus court, mais jamais plus longtemps), et pour créer une nouvelle ligne, appuyez simplement sur la touche Entrée (1 octet au lieu de 2 \n)! Voici votre code (non testé) un peu plus golfé (227 octets), la nouvelle ligne étant remplacée par :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
Je ne veux pas dire "interdit" mais "contre les règles", je veux simplement dire que ce n'est pas du tout utile, puisqu'un " forboucle" vaut toujours mieux qu'un " whileboucle";).
Blackhole

1
@ Michael_Dibbets En fait, je l'avais déjà écrit dans l'édition. Hm. Laisse moi voir. Haha, j'ai oublié de copier et de compter le dernier extrait. Duh : D Des choses comme ça se produisent si vous mettez à jour votre code avant le petit-déjeuner. Merci de l'avoir signalé.
insertusernamehere

14

Perl, 132 octets

Code de 155 octets + 17 pour -ln -MIO::Socket- 40 pour demander continuellement des URL

Comme avec la réponse de @ DigitalTrauma, l'analyse rationnelle du code HTML, faites-moi savoir si ce n'est pas acceptable. Ne continue plus à analyser les URL ... Je reviendrai plus tard ... Bien que Bash soit proche! Un grand merci à @ Schwern pour m'avoir sauvé 59 (!) Octets et à @ skmrx pour avoir corrigé le bogue permettant de réclamer le 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

Usage

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

J'ai corrigé un bogue et raccourci le code en supprimant le besoin de déclarer $ h et $ p ou d'avoir un chemin par défaut. De plus, il ne nécessite plus de suivi / sur l'hôte.
Schwern

1
Nous sommes le seul à battre maintenant. :)
Schwern

Je pense que j'ai fini pour la nuit. :)
Schwern

Puisque le script demande une autre URL au lieu de quitter, vous pouvez demander un supplément de -40 octets
svsd

1
@ DigitalTrauma, vous avez vraiment raison! J'ai réclamé le bonus grâce à skmrx qui a corrigé mon bogue avec '$ /' et je ne serais pas près du vôtre s'il n'y avait pas eu Schwern!
Dom Hastings

13

PowerShell, 315 294 268 262 254 octets

355 334 308 302 294 - 40 pour invite

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

Nécessite PowerShell v5

Toutes les fins de ligne (y compris celles incorporées dans la chaîne) sont uniquement des nouvelles lignes \n(merci Blackhole ) qui sont entièrement prises en charge par PowerShell (mais si vous testez, soyez prudent, ISE utilise \r\n).


4
+1 pour que les tâches administratives de mon serveur apparaissent beaucoup plus productives
que

HTTP nécessite CRLF, pas LF! [ HTTPSYNTAX ]
Brosse à dents

2
@ brosse à dents Ha! Point pris, mais la disposition de tolérance semble être pleinement en vigueur. Il est clair que cette tâche concerne ce qui fonctionne et non ce qui est correct (sinon, nous n'analyserions pas HTML avec regex et nous n'utiliserions que des bibliothèques TCP de bas niveau plutôt que des bibliothèques existantes bien testées).
Briantist

1
@briantist greenbytes.de/tech/webdav/rfc7230.html#rfc.section.3.5 indique qu '"un destinataire PEUT reconnaître un seul LF en tant que terminateur de ligne et ignorer tout CR précédent". J'ai lu cela comme signifiant que la plupart des serveurs web l'implémenteraient, et la question ne dit certainement pas qu'il doit générer des GET requêtes correctes:)
Brosse à dents

8

Script Groovy, 89 , 61 octets

Retour en boucle pour le bonus 101- 40 = 61

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

Avec juste des arguments, 89 octets

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

1
Groovy a dépassé tout le monde. Comme cela devrait être.
un spaghetto

1
@quartata Si ça reste comme ça, ce sera la première fois , alors ...;)
Geobits

11
"seules les API TCP de bas niveau sont autorisées"
Digital Trauma,

Oui, je suis d'accord avec @DigitalTrauma pour dire que cela n'utilise pas une API TCP de bas niveau. Les règles stipulent que vous devez diviser vous-même l'hôte et le chemin.
TheDoctor

6

Bash (peut tricher mais semble être dans les règles) 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

Merci à Digital Trauma.

Puisque je n'ai pas besoin de scinder l'URL, cela fonctionne aussi: 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
Je dirais que l'utilisation de ce convertisseur en ligne html2txt est une faille standard
Digital Trauma

1
Oui. Et j'utilise aussi cat pour que votre solution soit sans danger.
philcolbourn

5

C 512 octets

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

Sur la base de mon entrée ici , cela prend l'adresse Web sans le mot "https: //" en tête. Il ne gérera pas les <p>paires imbriquées correctement :(

Testé intensivement sur www.w3.org/People/Berners-Lee/
Cela fonctionne lorsque compilé avec Apple LLVM version 6.1.0 (clang-602.0.53) / Target: x86_64-apple-darwin14.1.1
Il a suffisamment de comportement indéfini pour que cela ne fonctionne pas ailleurs.


Je descendais à peu près la même piste (ces segfaults quand ils sont compilés avec gcc), mais il devrait être possible d’obtenir moins de 400 octets en C. Vous pouvez également supprimer l'include et "accéder" aux structures en tant que tableaux d'entiers à la place. Je reçois également des réponses "GET /% s HTTP / 1.1 \ r \ n \ r \ n \", mais le kilométrage peut varier en fonction du site ...
Comintern

5

Ruby, 118

Source de 147 octets; 11 octets ' -lprsocket'; -40 octets pour la mise en boucle.

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

Exemple d'utilisation:

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

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

Essai

Contribution:

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

Sortie:

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

Contribution:

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

Sortie:

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

Remarques

  • Ne supporte pas les <p>tags imbriqués
  • Prend en charge uniquement les <p>balises (insensible à la casse), se cassera à tous les autres formats de balises
  • Panics Boucle indéfiniment quand une erreur survient

4

C #, 727 octets - 40 = 687 octets

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

C'est un peu d'entraînement mais sûrement mémorable :)

Voici une version non-golfée:

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

Comme vous pouvez le constater, il existe des problèmes de fuite de mémoire en prime :)


Où est la fuite de mémoire? Je ne vois aucune usingdéclaration autour des cours d'eau, mais cela ne fait pas une fuite.
Gusdor

Vous pouvez couper quelques octets supplémentaires: input = input.trimStart ("http: //") remplacera la clause "if", et vous devriez pouvoir utiliser System.Text.Encoding.ASCII.GetBytes () directement sans avoir pour le stocker dans asciiEncoding en premier. Je pense que vous sortiriez même devant avec un "Using System"; ligne et se débarrasser d'une poignée de "System".
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))));

Usage:

node file.js www.example.com

Ou formaté

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
Mise en garde: cela fonctionnera pour les petites pages - les grandes pages émettent plusieurs événements de données.
Benjamin Gruenbaum

3

Python 2 - 212 209 octets

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

Vous pouvez enregistrer deux octets en supprimant les espaces après les deux points while h:et avant print g.
Skyler

Et un autre octet avec 'GET /%s HTTP/1.1\nHost:%s\n\n'.
Cees Timmerman

3

Python 2, 187 - 40 = 147 (141 dans une REPL)

Version compressée et en boucle de la réponse de 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))

Exemple:

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

En fait utile est ceci:

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

Exemple:

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 octets

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

Il y a du golf, mais c'est une version plus impitoyable, qui a besoin de l'adresse Web sans http://le début. Et si vous voulez accéder au répertoire racine, vous devez terminer l’adresse par un /. De plus, les <p>étiquettes doivent être en minuscules.

Ma version précédente ne traitait pas réellement les lignes contenant </p><p>correctement. Ceci est maintenant corrigé.

Sortie pour l'entrée 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>

Ne fonctionne toujours pas avec Wikipedia. Je pense que la raison est que Wikipedia utilise httpspour tout. Mais je ne sais pas.

La version suivante est un peu plus clémente avec l'entrée et elle peut aussi gérer les balises majuscules.

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

Je ne suis pas sûr de la "Connection:close"ligne. Ne semble pas être obligatoire. Je ne pouvais pas trouver un exemple qui fonctionnerait différemment avec ou sans cela.


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 n'est pas requis)

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

modifier * également pas difficile à mémoriser ^^


-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
Bienvenue dans Programming Puzzles & Code Golf! Malheureusement, cette soumission est invalide. La question n'autorise que les API TCP de bas niveau, vous ne pouvez donc pas l'utiliser InputStreamReader.
Dennis

1
Oh, je suis vraiment désolé et merci de l'avoir signalé. va faire mieux dans la prochaine réponse
Shalika Ashan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.