Самый маленький в мире веб-браузер

72

Предыстория:

Вы наслаждаетесь своей новой работой программиста в мегакультурной корпорации. Однако вы не можете просматривать веб-страницы, поскольку на вашем компьютере есть только CLI. Они также запускают развертки жестких дисков всех сотрудников, поэтому вы не можете просто загрузить большой веб-браузер CLI. Вы решаете сделать простой текстовый браузер настолько маленьким, насколько это возможно, чтобы вы могли запомнить его и каждый день вводить во временный файл.

Вызов:

Ваша задача - создать веб-браузер для гольфа в интерфейсе командной строки. Должно:

  • Возьмите один URL через args или stdin
  • Разделить directoryи hostкомпоненты URL
  • Отправьте простой HTTP-запрос hostна запрос указанногоdirectory
  • Печать содержимого любых <p>абзацев </p>тегов
  • И либо выйти, либо попросить другую страницу

Больше информации:

Простой HTTP-запрос выглядит так:

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

Окончание новой строки подчеркнуто.

Типичный ответ выглядит так:

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

Правила:

  • Нужно работать только на 80-м порту (SSL не требуется)
  • Вы не можете использовать Netcat
  • Какой бы язык программирования ни использовался, разрешены только низкоуровневые TCP API (кроме netcat)
  • Вы не можете использовать GUI, помните, это CLI
  • Вы не можете использовать HTML-парсеры, кроме встроенных (BeautifulSoup не является встроенным)
  • Бонус !! Если ваша программа зацикливается и запрашивает другой URL-адрес вместо выхода, -40 символов (если вы не используете рекурсию)
  • Нет сторонних программ. Помните, вы не можете ничего установить.
  • , поэтому выигрывает самый короткий счетчик байтов
Доктор
источник
7
Питон,import webbrowser;webbrowser.open(url)
Голубой
8
@muddyfish читайте правила
TheDoctor
4
Можете ли вы предоставить пример веб-страницы какого-то рода для тестирования этого? Трудно найти места, которые используют <p>: P
спагетто
52
Разрешено ли анализировать HTML с помощью регулярных выражений ? ;-)
Цифровая травма
3
Ограничение низкоуровневых интерфейсов сокетов, кажется, запрещает API уровня TCP большинства языков, которые имеют API уровня TCP.
Питер Тейлор

Ответы:

63

Pure Bash (без утилит), 200 байт - 40 бонусов = 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

Я думаю, что это зависит от спецификации, хотя, конечно, остерегайтесь парсинга HTML с помощью регулярных выражений. Думаю, что хуже, чем синтаксический анализ HTML с помощью регулярных выражений, является разбор HTML с использованием сопоставления с шаблоном оболочки.

Теперь это касается <p>...</p>нескольких строк. Каждый <p>...</p>находится на отдельной строке вывода:

$ 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
Тебе нужно запомнить это до завтра.
Конор О'Брайен,
14
+ ∞ для «разбора HTML с использованием сопоставления с шаблоном оболочки»
SztupY
76
-1 потому что ваш аватар - подсознательный обмен сообщениями
TheDoctor
1
... вы можете сделать TCP-соединения из Bash? Теперь я действительно в ужасе!
MathematicalOrchid
2
Примечание: /dev/tcpэто необязательное расширение, которое может отсутствовать в вашей сборке bash. Вы должны скомпилировать, --enable-net-redirectionsчтобы иметь это.
Крис Даун
21

PHP, 175 байтов (215 - 40 бонусов) 227 229 239 202 216 186 байтов

Приятного просмотра веб-страниц:

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

Читает URL-адреса STDINкак http://www.example.com/. Вывод абзацев через пробел " \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";
}

Первая версия, поддерживающая только один 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";

введите описание изображения здесь


Правки

  • Как указано в комментариях Braintist , я совершенно забыл указать путь. Это исправлено, спасибо. Добавлено 30 байт .
  • Сохранено 3 байта путем сброса $c(содержит содержимое страницы) $c=$i=parse_url(trim(fgets(STDIN)));вместо $c=''.
  • Сохранение 12 байтов путем замены \nновыми строками (5 байтов), одного whileцикла с for(2 байта), размещения почти всего в выражениях for(2 байта) и замены foreachна join(3 байта). Благодаря Черной дыре .
  • Сохранено 3 байта путем замены fgetsна stream_get_contentsБлагодаря bwoebi .
  • Сэкономили 5 байт , удалив повторную инициализацию, так $cкак она больше не нужна $c .
  • Сохранено 1 байт , удалив модификатор шаблона mиз регулярного выражения. Благодаря манатворке
insertusernamehere
источник
6
Связанный: stackoverflow.com/a/1732454/4766556
спагетто
1
@ briantist О, чувак, я полностью пропустил это. : D Спасибо, это сейчас исправлено.
insertusername здесь
1
Я не могу смириться с тем, что Perl превосходит PHP, поэтому не забывайте: whileэто запрещено при игре в гольф ( forчасто короче, но никогда не длиннее), а для перехода на новую строку просто нажмите enter (1 байт вместо 2 для \n)! Вот ваш (непроверенный) код, немного более удачный (227 байт), с заменой новой строки на :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
Я не имею в виду «запрещено» как «против правил», я просто имею в виду, что это вообще бесполезно, поскольку for-loop всегда лучше, чем while-loop;).
Blackhole
1
@MichaelDibbets На самом деле я сделал это уже как написано в редактировании. Гектометр Дайте-ка подумать. Ха-ха, я забыл скопировать и сосчитать последний фрагмент. Дух : D Такие вещи случаются, если вы обновите свой код перед завтраком. Спасибо за указание на это.
insertusername здесь
14

Perl, 132 байта

Код 155 байт + 17 для -ln -MIO::Socket- 40 для постоянного запроса URL

Как и в случае ответа @ DigitalTrauma, регулярного анализа HTML, дайте мне знать, если это не приемлемо. Больше не обрабатывает URL-адреса ... Я посмотрю на это позже ... Впрочем, близко к Bash! Большое спасибо @ Schwern за сохранение 59 (!) Байтов и @ skmrx за исправление ошибки, позволяющей получить бонус!

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

использование

$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>
Дом Гастингс
источник
Я исправил ошибку и сократил код, устранив необходимость объявлять $ h и $ p или иметь путь по умолчанию. Также больше не требуется трейлинг / на хосте.
Шверн
1
Теперь мы победим. :)
Шверн
Я думаю, что я закончил на ночь. :)
Шверн
Поскольку сценарий запрашивает другой URL вместо выхода, вы можете
запросить
1
@DigitalTrauma вы действительно правы! Я получил бонус благодаря skmrx, исправляющему мою ошибку с помощью $ /, и я не был бы рядом с вашим, если бы не Шверн!
Дом Гастингс
13

PowerShell, 315 294 268 262 254 байта

355 334 308 302 294 - 40 для быстрого

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

Требуется PowerShell v5

Все окончания строк (включая те, что встроены в строку) - это только новые строки \n(благодаря Blackhole ), которые полностью поддерживаются PowerShell (но если вы тестируете, будьте осторожны, ISE использует \r\n).

briantist
источник
4
+1 за то, что мои обязанности администратора сервера выглядят намного более продуктивными
чем
HTTP требует CRLF, а не LF! [ HTTPSYNTAX ]
Зубная щетка
2
@toothbrush Ха! Смысл принят, но положение о толерантности, похоже, в полной мере. Очевидно, что это задача о том, что работает, а не о том, что правильно (иначе мы бы не анализировали HTML с помощью регулярных выражений и не использовали бы низкоуровневые библиотеки TCP вместо хорошо протестированных существующих библиотек).
briantist
1
@briantist greenbytes.de/tech/webdav/rfc7230.html#rfc.section.3.5 говорит, что «получатель МОЖЕТ распознать один LF как терминатор строки и игнорировать любой предшествующий CR». Я понимаю, что это означает, что большинство веб-серверов будут реализовывать его, и в этом вопросе определенно не говорится, что он должен генерировать правильные GET запросы… :)
Зубная щетка
8

Groovy скрипт, 89 , 61 байт

Петля обратно бонусной 101- 40 = 61

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

Только с аргументами, 89 байтов

this.args[0].toURL().text.findAll(/<p>(?s)(.*?)<\/p>/).each{println it[3..it.length()-5]}
Rnet
источник
1
Groovy превзошел всех. Так, как это должно быть.
спагетто
1
@quartata Если так и останется, это будет впервые , так что ...;)
Geobits
11
«разрешены только низкоуровневые TCP API»
Digital Trauma
Да, я согласен с @DigitalTrauma, что здесь не используется низкоуровневый TCP API. Правила гласят, что вы должны разделить хост и путь самостоятельно.
Доктор
6

Bash (может быть обманывает, но, кажется, в рамках правил) 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

Благодаря Цифровой Травме.

Поскольку мне не нужно разделять URL, это также работает: 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
источник
8
Я бы сказал, что использование этого онлайн-конвертера html2txt - это стандартная лазейка
Digital Trauma
1
Да. И я также использую кошку, чтобы ваше решение было безопасным.
Филколборн
5

C 512 байт

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

Основываясь на моей записи здесь , он берет веб-адрес без ведущего "https: //". Он не будет <p>правильно обрабатывать вложенные пары :(

Протестировано на www.w3.org/People/Berners-Lee/
Он работает, когда компилируется с Apple LLVM version 6.1.0 (clang-602.0.53) / Target: x86_64-apple-darwin14.1.1
Он имеет достаточно неопределенное поведение, что он может не работать в другом месте

AShelly
источник
Я шел примерно по той же дорожке (эта ошибка при компиляции с gcc), но должна быть возможность получить менее 400 байт в C. Не уверен насчет clang, но вам не нужно объявлять возвращаемый тип main. Вместо этого вы также можете удалить include и «получить доступ» к структурам в виде целочисленных массивов. Я также получал ответы с "GET /% s HTTP / 1.1 \ r \ n \ r \ n \", но пробег может варьироваться в зависимости от сайта ...
Коминтерн
5

Руби, 118

Источник 147 байт; 11 байт ' -lprsocket'; -40 байт для циклов.

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

Пример использования:

$ 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
источник
4

AutoIt , 347 байт

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

тестирование

Входные данные:

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

Выход:

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

Входные данные:

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

Выход:

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

замечания

  • Не поддерживает вложенные <p>теги
  • Поддерживает только <p>теги (без учета регистра), будет прерываться на любой другой формат тега
  • Паника зацикливается на неопределенное время при возникновении любой ошибки
mınxomaτ
источник
4

C #, 727 байт - 40 = 687 байт

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

Это немного тренировки, но, безусловно, запоминающийся :)

Вот негольфированная версия:

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

Как видите, в качестве бонуса есть проблемы с утечкой памяти :)

Стефан Шинкель
источник
Где утечка памяти? Я не вижу никаких usingзаявлений о потоках, но это не делает утечку.
Gusdor
Вы можете обрезать еще несколько байтов: input = input.trimStart ("http: //") заменит предложение "if", и вы сможете использовать System.Text.Encoding.ASCII.GetBytes () напрямую, не имея сначала сохранить его в asciiEncoding. Я думаю, что вы даже выступили с «Использование системы»; линия и избавиться от горстки "системы".
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))));

Использование:

node file.js www.example.com

Или отформатированный

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
Предостережение: это будет работать для маленьких страниц - большие страницы генерируют несколько событий данных.
Бенджамин Грюнбаум
3

Python 2 - 212 209 байт

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
Зак Критов
источник
Вы можете сохранить два байта, удаляя пробелы после двоеточия while h:и до print g.
Скайлер
И еще один байт с 'GET /%s HTTP/1.1\nHost:%s\n\n'.
Сис Тиммерман
3

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

Сжатый и зацикленный вариант ответа Зака :

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

Пример:

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

На самом деле полезно это:

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

Пример:

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 байт

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

Гольф это, но это более неумолимая версия, которая требует веб-адрес без http://в начале. И если вы хотите получить доступ к корневому каталогу, вы должны закончить адрес с /. Кроме того, <p>теги должны быть в нижнем регистре.

Моя ранняя версия на самом деле не обрабатывает строки, содержащие </p><p>правильно. Это сейчас исправлено.

Выход для ввода 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>

Все еще не работает с Википедией. Я думаю, причина в том, что Википедия использует httpsдля всего. Но я не знаю

Следующая версия немного прощает ввод и может обрабатывать теги верхнего регистра.

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

Я не уверен насчет "Connection:close"линии. Не кажется обязательным. Я не мог найти пример, который работал бы по-другому с или без него.

Cabbie407
источник
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 (прокси не требуется)

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

редактировать * также не трудно запомнить ^^

dwana
источник
-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
Добро пожаловать в Программирование Пазлов и Code Golf! К сожалению, это представление недействительно. Вопрос разрешает только низкоуровневые TCP API, поэтому вы не можете использовать InputStreamReader.
Деннис
1
О, мне очень жаль и спасибо, что указали на это. будет лучше в следующем ответе
Шалика Ашан