Najmniejsza na świecie przeglądarka internetowa


72

Historia:

Lubisz swoją nową pracę programistyczną w wielkiej korporacji. Nie możesz jednak przeglądać Internetu, ponieważ Twój komputer ma tylko interfejs CLI. Przeszukują również dyski twarde wszystkich pracowników, więc nie można po prostu pobrać dużej przeglądarki internetowej CLI. Decydujesz się stworzyć prostą przeglądarkę tekstową, która jest tak mała, jak to możliwe, abyś mógł ją zapamiętać i wpisywać do pliku tymczasowego każdego dnia.

Wyzwanie:

Twoim zadaniem jest stworzenie gry w golfa w interfejsie wiersza poleceń. Powinno:

  • Weź pojedynczy adres URL za pośrednictwem args lub stdin
  • Podziel directoryi hostskładniki adresu URL
  • Wyślij proste żądanie HTTP do, hostaby poprosić o wspomnianedirectory
  • Wydrukuj zawartość dowolnych znaczników <p>akapitu</p>
  • I wyjdź lub poproś o kolejną stronę

Więcej informacji:

Proste żądanie HTTP wygląda następująco:

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

Podkreślono zakończenie nowych linii.

Typowa odpowiedź wygląda następująco:

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

Zasady:

  • Musi działać tylko na porcie 80 (nie wymaga SSL)
  • Nie możesz używać NetCat
  • Niezależnie od używanego języka programowania dozwolone są tylko interfejsy API niskiego poziomu TCP (z wyjątkiem netcat)
  • Być może nie używać GUI, należy pamiętać, że jest to CLI
  • Nie możesz używać parserów HTML, z wyjątkiem wbudowanych (BeautifulSoup nie jest wbudowanym)
  • Premia!! Jeśli Twój program zapętla się i prosi o podanie innego adresu URL zamiast wyjścia, -40 znaków (o ile nie używasz rekurencji)
  • Brak programów innych firm. Pamiętaj, że nie możesz niczego zainstalować.
  • , więc wygrywa najkrótsza liczba bajtów

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

8
@muddyfish przeczytaj zasady
TheDoctor

4
Czy możesz podać przykładową stronę internetową do testowania tego? Trudno jest znaleźć miejsca, które używają <p>: P
spaghetto


3
Ograniczenie do interfejsów gniazd niskiego poziomu wydaje się zabraniać interfejsów API na poziomie TCP w większości języków, które mają interfejsy API na poziomie TCP.
Peter Taylor

Odpowiedzi:


63

Pure Bash (bez narzędzi), 200 bajtów - 40 bonusów = 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

Myślę, że to zależy od specyfikacji, choć oczywiście uważaj na parsowanie HTML za pomocą regex. Myślę, że jedyną rzeczą gorszą niż parsowanie HTML za pomocą regex jest parsowanie HTML za pomocą dopasowania wzorca powłoki.

Teraz dotyczy to <p>...</p>łączenia wielu linii. Każdy <p>...</p>znajduje się w osobnym wierszu danych wyjściowych:

$ 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
Musisz to zapamiętać do jutra.
Conor O'Brien,

14
+ ∞ za „parsowanie HTML przy użyciu dopasowania wzorca powłoki”
SztupY

76
-1, ponieważ twój awatar to podprogowe wiadomości
TheDoctor,

1
... możesz nawiązywać połączenia TCP z Bash? Teraz jestem naprawdę przerażony!
MathematicalOrchid

2
Uwaga: /dev/tcpjest opcjonalnym rozszerzeniem i może nie być obecny w twojej wersji bash. Musisz go skompilować, --enable-net-redirectionsaby go mieć.
Chris Down

21

PHP, 175 bajtów (premia 215–40 ) 227 229 239 202 216 186 bajtów

Miłej zabawy podczas przeglądania sieci:

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

Czyta adresy URL z STDINpodobnych http://www.example.com/. Wypisuje akapity oddzielone znakiem nowej linii „ \n”.


Nie golfił

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

Pierwsza wersja obsługuje tylko jeden adres 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";

wprowadź opis zdjęcia tutaj


Edycje

  • Jak wskazano w komentarzach Braintist , całkowicie zapomniałem podać ścieżkę. To już naprawione, dzięki. Dodano 30 bajtów .
  • Zapisano 3 bajty , resetując $c(przechowuje zawartość strony) za pomocą $c=$i=parse_url(trim(fgets(STDIN)));zamiast $c=''.
  • Zapisane 12 bajtów zastępując \nnowych linii (5 bajtów), jeden while-loop z for(2 bajty) umieszczenie prawie wszystko w wyrażeniach for(2 bajty) i zastępując foreachz join(3 bajty). Dzięki Blackhole .
  • Zapisane 3 bajty zastępując fgetsze stream_get_contentsDzięki bwoebi .
  • Zaoszczędzono 5 bajtów , usuwając ponowną inicjalizację, $cponieważ nie jest już wcale potrzebna $c .
  • Zapisano 1 bajt , usuwając modyfikator wzorca mz Regex. Dzięki manatwork


1
@Briantist O rany, zupełnie za tym tęskniłem. : D Dzięki, teraz jest naprawione.
inserttusernamehere

1
Nie mogę znieść, że Perl bije PHP, więc nie zapominaj: whilejest zabronione podczas gry w golfa ( forczęsto jest krótsze, ale nigdy nie dłuższe), a aby rozpocząć nową linię, wystarczy nacisnąć enter (1 bajt zamiast 2 dla \n)! Oto twój (nieprzetestowany) kod nieco bardziej golfowy (227 bajtów), a nowy wiersz został zastąpiony przez :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
Nie mam na myśli „zabronione” jako „niezgodne z regułami”, po prostu mam na myśli, że to w ogóle nie jest przydatne, ponieważ forpętla jest zawsze lepsza niż whilepętla;).
Blackhole

1
@MichaelDibbets Właściwie zrobiłem to już tak, jak napisano w edycji. Hm Daj mi zobaczyć. Haha, zapomniałem skopiować i policzyć ostatni fragment. Duh : D Tak się stanie, jeśli zaktualizujesz swój kod przed śniadaniem. Dzięki za zwrócenie na to uwagi.
inserttusernamehere

14

Perl, 132 bajty

Kod 155 bajtów + 17 dla -ln -MIO::Socket- 40 dla ciągłego pytania o adresy URL

Podobnie jak w przypadku odpowiedzi @ DigitalTrauma, analizowanie wyrażeń regularnych HTML, daj mi znać, jeśli jest to nie do przyjęcia. Nie przetwarza już parsujących adresów URL ... Zajmę się tym później ... Jednak blisko Bash! Ogromne podziękowania dla @ Schwern za uratowanie mnie 59 (!) Bajtów i @ skmrx za naprawienie błędu, aby umożliwić roszczenie o 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

Stosowanie

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

Naprawiłem błąd i skróciłem kod, usuwając potrzebę deklarowania $ h i $ p lub posiadania domyślnej ścieżki. To również nie wymaga trailing / na hoście.
Schwern

1
Teraz jesteśmy tymi, którzy pokonali. :)
Schwern

Myślę, że skończyłem na noc. :)
Schwern

Ponieważ skrypt prosi o podanie innego adresu URL zamiast wyjścia, możesz zażądać dodatkowych -40 bajtów
svsd

1
@DigitalTrauma naprawdę masz rację! Odebrałem bonus dzięki skmrx naprawiającemu mój błąd za pomocą „$ /” i nie byłbym blisko twojego, gdyby nie Schwern!
Dom Hastings,

13

PowerShell, 315 294 268 262 254 bajtów

355 334 308 302 294 - 40 na zapytanie

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

Wymaga PowerShell v5

Wszystkie zakończenia linii (w tym te osadzone w ciągu) są tylko nowymi liniami \n(dzięki Blackhole ), który jest w pełni obsługiwany przez PowerShell (ale jeśli testujesz, bądź ostrożny; używa ISE \r\n).


4
+1 za sprawienie, że obowiązki administracyjne mojego serwera wydają się znacznie bardziej produktywne
niż do

HTTP wymaga CRLF, a nie LF! [ HTTPSYNTAX ]
Szczoteczka do zębów

2
@toothbrush Ha! Podjęto punkt, ale wydaje się, że przepis dotyczący tolerancji jest w pełni skuteczny. Najwyraźniej to zadanie dotyczy tego, co działa, a nie tego, co jest poprawne (inaczej nie analizowalibyśmy HTML za pomocą wyrażeń regularnych i nie korzystalibyśmy z bibliotek TCP niskiego poziomu zamiast dobrze przetestowanych istniejących bibliotek).
briantist

1
@briantist greenbytes.de/tech/webdav/rfc7230.html#rfc.section.3.5 mówi, że „odbiorca MOŻE rozpoznać pojedynczy LF jako terminator linii i zignorować wszelkie poprzednie CR”. Przeczytałem, że to znaczy, że większość serwerów WWW to zaimplementuje, a pytanie zdecydowanie nie mówi, że musi generować prawidłowe GET żądania… :)
Szczoteczka do zębów

8

Groovy script, 89 , 61 bajtów

Pętlę powrotną do premii 101- 40 = 61

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

Z tylko argumentami, 89 bajtów

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

1
Groovy obezwładnił wszystkich. Tak jak powinno być.
spaghetto

1
@quartata Jeśli tak pozostanie, będzie to pierwszy raz , więc ...;)
Geobits

11
„dozwolone są tylko niskopoziomowe interfejsy API TCP”
Digital Trauma

Tak, zgodzę się z @DigitalTrauma, że ​​nie używa interfejsu API niskiego poziomu TCP. Reguły mówią, że musisz sam podzielić hosta i ścieżkę.
TheDoctor,

6

Bash (może oszukiwać, ale wydaje się być zgodny z regułami) 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

Dzięki Digital Trauma.

Ponieważ nie muszę dzielić adresu URL, działa to również: 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
Twierdziłbym, że korzystanie z tego internetowego konwertera html2txt jest standardową luką
Digital Trauma

1
Tak. Używam również cat, aby twoje rozwiązanie było bezpieczne.
philcolbourn

5

C 512 bajtów

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

Opierając się luźno na moim wpisie tutaj , pobiera adres internetowy bez wiodącego „https: //”. Nie obsługuje <p>poprawnie zagnieżdżonych par :(

Przebadany szeroko. www.w3.org/People/Berners-Lee/
Działa po kompilacji Apple LLVM version 6.1.0 (clang-602.0.53) / Target: x86_64-apple-darwin14.1.1
Ma wystarczająco niezdefiniowane zachowanie, że może nie działać nigdzie indziej.


Szedłem mniej więcej tą samą ścieżką (ta segfaga przy kompilacji z gcc), ale powinno być możliwe uzyskanie poniżej 400 bajtów w C. Nie jestem pewien co do clang, ale nie powinieneś deklarować typu zwracanego main. Zamiast tego możesz również usunąć struktury include i „access” jako tablice liczb całkowitych. Otrzymuję również odpowiedzi za pomocą „GET /% s HTTP / 1.1 \ r \ n \ r \ n \”, ale przebieg może się różnić w zależności od strony ...
Comintern,

5

Ruby, 118

Źródło 147 bajtów; 11 bajtów ' -lprsocket'; -40 bajtów do zapętlenia.

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

Przykład użycia:

$ 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 bajtów

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

Testowanie

Wejście:

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

Wynik:

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

Wejście:

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

Wynik:

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

Uwagi

  • Nie obsługuje zagnieżdżonych <p>tagów
  • Obsługuje tylko <p>tagi (bez rozróżniania wielkości liter), zepsuje się na każdym innym formacie tagu
  • Panika Pętle bez końca w przypadku wystąpienia błędu

4

C #, 727 bajtów - 40 = 687 bajtów

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

Trochę treningu, ale na pewno niezapomniany :)

Oto wersja bez golfa:

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

Jak widać, występują problemy z wyciekiem pamięci jako bonus :)


Gdzie jest wyciek pamięci? Nie widzę żadnych usingoświadczeń wokół strumieni, ale to nie powoduje wycieku.
Gusdor

Możesz przyciąć jeszcze kilka bajtów: input = input.trimStart („http: //”) zastąpi klauzulę „if” i powinieneś być w stanie używać System.Text.Encoding.ASCII.GetBytes () bezpośrednio bez konieczności najpierw zapisać w asciiEncoding. Myślę, że nawet wyszedłbyś na przód z „Korzystanie z systemu”; i pozbycie się garści „Systemu”.
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))));

Stosowanie:

node file.js www.example.com

Lub sformatowane

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
Uwaga: będzie to działać na małych stronach - większe strony emitują wiele zdarzeń danych.
Benjamin Gruenbaum

3

Python 2 - 212 209 bajtów

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

Możesz zaoszczędzić dwa bajty, usuwając spacje po dwukropku while h:przed i przed print g.
Skyler

I kolejny bajt z 'GET /%s HTTP/1.1\nHost:%s\n\n'.
Cees Timmerman

3

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

Skompresowana i zapętlona wersja odpowiedzi 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))

Przykład:

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

Właściwie przydatne jest to:

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

Przykład:

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 bajtów

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

Grałem w golfa, ale jest to bardziej bezlitosna wersja, która wymaga adresu internetowego bez http://początku. A jeśli chcesz uzyskać dostęp do katalogu głównego, musisz zakończyć adres znakiem /. Ponadto <p>tagi muszą być pisane małymi literami.

Moja wcześniejsza wersja faktycznie nie obsługiwała wierszy zawierających </p><p>poprawnie. To jest teraz naprawione.

Wyjście dla danych wejściowych 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>

Nadal nie działa z Wikipedią. Myślę, że powodem jest to, że Wikipedia używa httpsdo wszystkiego. Ale nie wiem.

Poniższa wersja jest nieco bardziej wybaczająca z wejściem i może również obsługiwać duże litery.

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

Nie jestem pewien co do "Connection:close"linii. Nie wydaje się to obowiązkowe. Nie mogłem znaleźć przykładu, który działałby inaczej z nim lub bez niego.


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

Niegolfowany (proxy nie jest wymagane)

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

edytuj * też nie trudno zapamiętać ^^


-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
Witamy w Programowaniu Puzzle i Code Golf! Niestety to zgłoszenie jest nieprawidłowe. Pytanie dopuszcza tylko interfejsy API niskiego poziomu TCP, więc nie można używać InputStreamReader.
Dennis

1
Tak mi przykro i dziękuję za wskazanie tego. zrobi lepiej w następnej odpowiedzi
Shalika Ashan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.