El navegador web más pequeño del mundo

72

Trasfondo:

Disfrutas tu nuevo trabajo de programación en una mega-multi-corporación. Sin embargo, no puede navegar por la web ya que su computadora solo tiene una CLI. También ejecutan barridos de los discos duros de todos los empleados, por lo que no puede simplemente descargar un navegador web CLI grande. Decide crear un navegador de texto simple que sea lo más pequeño posible para que pueda memorizarlo y escribirlo en un archivo temporal todos los días.

Desafío:

Su tarea es crear un navegador web con golf dentro de una interfaz de línea de comandos. Debería:

  • Tome una sola URL a través de args o stdin
  • Dividir los componentes directoryy hostde la URL
  • Enviar una solicitud HTTP simple a la hostsolicitud de dichodirectory
  • Imprima el contenido de cualquier etiqueta de <p>párrafo</p>
  • Y salga o solicite otra página

Más información:

Una simple solicitud HTTP se ve así:

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

Poner fin a las nuevas líneas enfatizadas.

Una respuesta típica se ve así:

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

Reglas:

  • Solo necesita trabajar en el puerto 80 (no se necesita SSL)
  • No puedes usar netcat
  • Independientemente del lenguaje de programación utilizado, solo se permiten API TCP de bajo nivel (excepto netcat)
  • Es posible que no usar interfaz gráfica de usuario, recuerda, es una CLI
  • No puede usar analizadores HTML, excepto los incorporados (BeautifulSoup no es incorporado)
  • ¡¡Prima!! Si su programa retrocede y solicita otra URL en lugar de salir, -40 caracteres (siempre que no use la recursividad)
  • No hay programas de terceros. Recuerda, no puedes instalar nada.
  • , por lo que gana el conteo de bytes más corto
TheDoctor
fuente
77
Python,import webbrowser;webbrowser.open(url)
Azul
8
@muddyfish lee las reglas
TheDoctor
44
¿Puede proporcionar una página web de muestra de algún tipo para probar esto? Es difícil encontrar lugares que usen <p>: P
un spaghetto
52
¿Se nos permite analizar HTML utilizando expresiones regulares ? ;-)
Digital Trauma
3
La restricción a las interfaces de socket de bajo nivel parece prohibir las API de nivel TCP de la mayoría de los idiomas que tienen API de nivel TCP.
Peter Taylor

Respuestas:

63

Pure Bash (sin utilidades), 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

Creo que esto está a la altura de las especificaciones, aunque , por supuesto, ten cuidado con el análisis HTML utilizando expresiones regulares Creo que lo único peor que analizar HTML usando regex es analizar HTML usando la coincidencia de patrones de shell.

Ahora se trata de <p>...</p>abarcar varias líneas. Cada uno <p>...</p>está en una línea de salida separada:

$ 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>
$ 
Trauma digital
fuente
35
Necesitas memorizar esto para mañana.
Conor O'Brien
14
+ ∞ para "análisis de HTML utilizando coincidencia de patrones shell"
SztupY
76
-1 porque tu avatar es un mensaje subliminal
TheDoctor
1
... puedes hacer conexiones TCP desde Bash? ¡Ahora estoy realmente aterrorizado!
MathematicalOrchid
2
Nota: /dev/tcpes una extensión opcional y puede no estar presente en su compilación de bash. Necesitas compilar --enable-net-redirectionspara tenerlo.
Chris Down
21

PHP, 175 bytes (215 - 40 bonificación) 227 229 239 202 216 186 bytes

Diviértete navegando por la 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])."
");

Lee las URL de me STDINgusta http://www.example.com/. Emite párrafos separados por nueva línea " \n".


Sin golf

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

Primera versión que admite solo una 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";

ingrese la descripción de la imagen aquí


Ediciones

  • Como se señaló en los comentarios de Braintist , olvidé por completo incluir el camino. Eso está arreglado ahora, gracias. Se agregaron 30 bytes .
  • Se guardaron 3 bytes al restablecer $c(contiene el contenido de la página) con en $c=$i=parse_url(trim(fgets(STDIN)));lugar de $c=''.
  • Se guardaron 12 bytes al reemplazar \ncon nuevas líneas (5 bytes), un whilebucle con for(2 bytes), colocando casi todo en las expresiones de for(2 bytes) y al reemplazar foreachcon join(3 bytes). Gracias a Blackhole .
  • Se guardaron 3 bytes al reemplazar fgetscon stream_get_contentsGracias a bwoebi .
  • Ahorró 5 bytes al eliminar la reinicialización de, $cya que ya no es necesario $c .
  • Se guardó 1 byte al eliminar el modificador de patrón mde Regex. Gracias a manatwork
insertusernamehere
fuente
66
Relacionado: stackoverflow.com/a/1732454/4766556
un spaghetto
1
@briantist Oh hombre, lo extrañé por completo. : D Gracias, ya está arreglado.
insertusernamehere
1
No puedo soportar que Perl venza a PHP, así que no lo olvides: whileestá prohibido jugar al golf (a formenudo es más corto pero nunca más largo), y para hacer una nueva línea, solo presiona enter (1 byte en lugar de 2 para \n). Aquí está su código (no probado) un poco más golfizado (227 bytes), con la nueva línea reemplazada por :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
No me refiero a "prohibido" como "en contra de las reglas", solo quiero decir que no es útil en absoluto, ya que un forbucle siempre es mejor que un whilebucle;
Blackhole
1
@MichaelDibbets En realidad ya lo hice tal como está escrito en la edición. Hm. Déjame ver. Jaja, olvidé copiar y contar el fragmento final. Duh : D Suceden cosas así, si actualizas tu código antes del desayuno. Gracias por mencionarlo.
insertusernamehere
14

Perl, 132 bytes

Código de 155 bytes + 17 para -ln -MIO::Socket- 40 para pedir continuamente URLs

Al igual que con la respuesta de @ DigitalTrauma, regex analizando HTML, avíseme si eso no es aceptable. Ya no sigue analizando las URL ... Lo veré más tarde ... ¡Cerca de Bash! ¡ Muchas gracias a @ Schwern por salvarme 59 (!) Bytes y a @ skmrx por corregir el error para permitir un reclamo de la bonificación!

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>
Dom Hastings
fuente
Solucioné un error y acorté el código al eliminar la necesidad de declarar $ h y $ p o tener una ruta predeterminada. También ya no requiere un seguimiento / en el host.
Schwern
1
Somos los que vencemos ahora. :)
Schwern
Creo que he terminado por la noche. :)
Schwern
Como el script solicita otra URL en lugar de salir, puede reclamar -40 bytes adicionales
svsd
1
@DigitalTrauma tienes razón! ¡He reclamado la bonificación gracias a que skmrx solucionó mi error con '$ /' y no estaría cerca del tuyo si no fuera por Schwern!
Dom Hastings
13

PowerShell, 315 294 268 262 254 bytes

355334308302294-40 para solicitud

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

Requiere PowerShell v5

Todas las terminaciones de línea (incluidas las incrustadas en la cadena) son solo líneas nuevas \n(gracias a Blackhole ) que es totalmente compatible con PowerShell (pero si está probando, tenga cuidado; ISE usa \r\n).

briantista
fuente
44
1 para hacer mis tareas de administración del servidor parece mucho más productivo
thanby
HTTP requiere CRLF, no LF! [ HTTPSYNTAX ]
Cepillo de dientes
2
@toothbrush Ja! Punto tomado, pero la disposición de tolerancia parece estar en pleno efecto. Claramente, esta tarea se trata de lo que funciona y no de lo que es correcto (de lo contrario no estaríamos analizando HTML con expresiones regulares y utilizando bibliotecas TCP de bajo nivel en lugar de bibliotecas existentes bien probadas).
briantist
1
@briantist greenbytes.de/tech/webdav/rfc7230.html#rfc.section.3.5 dice que "un destinatario PUEDE reconocer un solo LF como un terminador de línea e ignorar cualquier CR anterior". Leí que, en el sentido de que la mayoría de los servidores web lo implementarían, y la pregunta definitivamente no dice que debe generar solicitudes correctas GET ... :)
Cepillo de dientes
8

Groovy script, 89 , 61 bytes

Loop de vuelta para bono 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 bytes

this.args[0].toURL().text.findAll(/<p>(?s)(.*?)<\/p>/).each{println it[3..it.length()-5]}
Rnet
fuente
1
Groovy superó a todos. Como debería ser.
un spaghetto
1
@quartata Si sigue así, será la primera vez , así que ...;)
Geobits
11
"solo se permiten API TCP de bajo nivel"
Digital Trauma
Sí, voy a estar de acuerdo con @DigitalTrauma en que esto no está utilizando una API TCP de bajo nivel. Las reglas establecen que debe dividir el host y la ruta por su cuenta.
TheDoctor
6

Bash (puede estar haciendo trampa pero parece estar dentro de las reglas) 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

Gracias a Digital Trauma.

Como no necesito dividir la URL, esto también funciona: 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
philcolbourn
fuente
8
Yo diría que el uso de este convertidor html2txt en línea es una laguna estándar
Digital Trauma
1
Si. Y también uso cat para que su solución sea segura.
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);}}} 

Basado libremente en mi entrada aquí , toma la dirección web sin un "https: //" principal. No manejará <p>pares anidados correctamente :(

Probado exhaustivamente en www.w3.org/People/Berners-Lee/
Funciona cuando se compila con Apple LLVM version 6.1.0 (clang-602.0.53) / Target: x86_64-apple-darwin14.1.1
Tiene un comportamiento indefinido suficiente que puede no funcionar en ningún otro lugar.

AShelly
fuente
Estaba bajando aproximadamente por la misma pista (esto se produce por defecto cuando se compila con gcc), pero debería ser posible obtener menos de 400 bytes en C. No estoy seguro acerca de clang, pero no debería tener que declarar el tipo de retorno de main. También puede eliminar la inclusión y "acceder" a las estructuras como matrices enteras. También he recibido respuestas con "GET /% s HTTP / 1.1 \ r \ n \ r \ n \", pero el kilometraje puede variar según el sitio ...
Comintern
5

Ruby, 118

Fuente de 147 bytes; 11 bytes ' -lprsocket'; -40 bytes para bucle.

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

Ejemplo de uso:

$ 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>.
ezrast
fuente
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

Pruebas

Entrada:

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

Salida:

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

Entrada:

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

Salida:

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

Observaciones

  • No admite <p>etiquetas anidadas
  • Solo admite <p>etiquetas (no distingue entre mayúsculas y minúsculas), se romperá en cualquier otro formato de etiqueta
  • Pánico Loops indefinidamente cuando se produce cualquier error
mınxomaτ
fuente
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 un poco de entrenamiento pero seguramente memorable :)

Aquí hay una versión sin golf:

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

Como puede ver, hay problemas de pérdida de memoria como un bono :)

Stephan Schinkel
fuente
¿Dónde está la pérdida de memoria? No veo usingdeclaraciones en torno a las transmisiones, pero eso no hace una fuga.
Gusdor
Puede recortar algunos bytes más: input = input.trimStart ("http: //") reemplazará la cláusula "if", y debería poder usar System.Text.Encoding.ASCII.GetBytes () directamente sin tener para almacenarlo en asciiEncoding primero. Creo que incluso saldrías adelante con un "Uso del sistema"; línea y deshacerse de un puñado de "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 formateado

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)))
});
Benjamin Gruenbaum
fuente
1
Advertencia: esto funcionará para páginas pequeñas: las páginas más grandes emiten múltiples eventos de datos.
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
Criterios de Zac
fuente
Puede guardar dos bytes quitando espacios en blanco después de los dos puntos while h:y antes print g.
Skyler
Y otro byte con 'GET /%s HTTP/1.1\nHost:%s\n\n'.
Cees Timmerman
3

Python 2, 187-40 = 147 (141 en una REPL)

Versión comprimida y en bucle de la respuesta 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))

Ejemplo:

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

Realmente útil es esto:

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

Ejemplo:

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]
Cees Timmerman
fuente
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)}

Lo descarté, pero esta es una versión más implacable, que necesita la dirección web sin http://al principio. Y si desea acceder al directorio raíz, debe finalizar la dirección con un /. Además, las <p>etiquetas deben ser minúsculas.

Mi versión anterior en realidad no manejaba las líneas que contenían </p><p>correctamente. Esto ya está arreglado.

Salida para entrada 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>

Todavía no funciona con Wikipedia. Creo que la razón es que Wikipedia usa httpspara todo. Pero no lo se.

La siguiente versión es un poco más indulgente con la entrada y también puede manejar etiquetas en mayúsculas.

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

No estoy seguro de la "Connection:close"línea. No parece ser obligatorio. No pude encontrar un ejemplo que funcionaría diferente con o sin él.

Cabbie407
fuente
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 "")

Sin golf (no se requiere 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 "")

editar * también no es difícil de memorizar ^^

dwana
fuente
-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) {

        }
    }

}
Shalika Ashan
fuente
2
¡Bienvenido a Programming Puzzles & Code Golf! Lamentablemente, este envío no es válido. La pregunta solo permite las API TCP de bajo nivel, por lo que no puede usarlas InputStreamReader.
Dennis
1
Oh, lo siento mucho y gracias por señalarlo. lo hará mejor en la próxima respuesta
Shalika Ashan