Trình duyệt web nhỏ nhất thế giới


72

Cơ sở:

Bạn thích công việc lập trình mới của mình tại một tập đoàn lớn. Tuy nhiên, bạn không được phép duyệt web vì máy tính của bạn chỉ có CLI. Họ cũng chạy quét tất cả các ổ cứng của nhân viên, vì vậy bạn không thể tải xuống một trình duyệt web CLI lớn. Bạn quyết định tạo một trình duyệt văn bản đơn giản, nhỏ nhất có thể để bạn có thể ghi nhớ nó và nhập nó vào một tệp tạm thời mỗi ngày.

Thử thách:

Nhiệm vụ của bạn là tạo một trình duyệt web được đánh gôn trong giao diện dòng lệnh. Nó nên:

  • Lấy một URL trong thông qua args hoặc stdin
  • Tách directoryhostcác thành phần của URL
  • Gửi một yêu cầu HTTP đơn giản hostđến yêu cầu đã nóidirectory
  • In nội dung của bất kỳ thẻ <p>đoạn </p>nào
  • Và thoát hoặc yêu cầu một trang khác

Thêm thông tin:

Một yêu cầu HTTP đơn giản trông như thế này:

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

Kết thúc dòng mới nhấn mạnh.

Một phản ứng điển hình trông giống như:

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

Quy tắc:

  • Nó chỉ cần hoạt động trên cổng 80 (không cần SSL)
  • Bạn không thể sử dụng netcat
  • Dù sử dụng ngôn ngữ lập trình nào, chỉ các API TCP cấp thấp mới được phép (ngoại trừ netcat)
  • Bạn không thể sử dụng GUI, hãy nhớ, đó là CLI
  • Bạn không được sử dụng các trình phân tích cú pháp HTML, ngoại trừ các trình phân tích dựng sẵn (BeautifulSoup không phải là một nội dung)
  • Thêm!! Nếu chương trình của bạn lặp lại và yêu cầu một URL khác thay vì thoát, -40 ký tự (miễn là bạn không sử dụng đệ quy)
  • Không có chương trình của bên thứ ba. Hãy nhớ rằng, bạn không thể cài đặt bất cứ điều gì.
  • , vì vậy số byte ngắn nhất sẽ thắng

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

8
@muddyfish đọc các quy tắc
TheDoctor

4
Bạn có thể cung cấp một trang web mẫu của một số loại để thử nghiệm điều này? Thật khó để tìm thấy những nơi sử dụng <p>: P
một spaghetto

52
Chúng tôi có được phép phân tích HTML bằng regex không? ;-)
Chấn thương kỹ thuật số

3
Hạn chế đối với các giao diện ổ cắm cấp thấp dường như cấm các API cấp TCP của hầu hết các ngôn ngữ có API cấp TCP.
Peter Taylor

Câu trả lời:


63

Pure Bash (không có tiện ích), 200 byte - 40 phần thưởng = 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

Tôi nghĩ rằng điều này tùy thuộc vào thông số kỹ thuật, mặc dù tất nhiên coi chừng phân tích HTML bằng regex Tôi nghĩ điều duy nhất tồi tệ hơn là phân tích HTML bằng regex là phân tích HTML bằng cách sử dụng khớp mẫu.

Điều này bây giờ liên quan đến <p>...</p>kéo dài nhiều dòng. Mỗi cái <p>...</p>nằm trên một dòng đầu ra riêng biệt:

$ 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
Bạn cần phải ghi nhớ điều này vào ngày mai.
Conor O'Brien

14
+ ∞ cho "phân tích cú pháp HTML bằng cách sử dụng khớp mẫu"
SztupY

76
-1 vì hình đại diện của bạn là tin nhắn thăng hoa
TheDoctor

1
... Bạn có thể tạo kết nối TCP từ Bash? Bây giờ tôi thực sự kinh hoàng!
Toán học,

2
Lưu ý: /dev/tcplà một tiện ích mở rộng tùy chọn và có thể không có trong bản bash của bạn. Bạn cần phải biên dịch với --enable-net-redirectionsđể có nó.
Chris Down

21

PHP, 175 byte (phần thưởng 215 - 40) 227 229 239 202 216 186 byte

Hãy vui vẻ duyệt 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])."
");

Đọc URL từ STDINthích http://www.example.com/. Các đoạn đầu ra được phân tách bằng dòng mới " \n".


Ung dung

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

Phiên bản đầu tiên chỉ hỗ trợ một 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";

nhập mô tả hình ảnh ở đây


Chỉnh sửa

  • Như được chỉ ra trong các ý kiến ​​của Braintist , tôi hoàn toàn quên bao gồm đường dẫn. Bây giờ đã sửa rồi, cảm ơn. Đã thêm 30 byte .
  • Đã lưu 3 byte bằng cách đặt lại $c(giữ nội dung trang) $c=$i=parse_url(trim(fgets(STDIN)));thay vì $c=''.
  • Đã lưu 12 byte bằng cách thay thế \nbằng các dòng mới (5 byte), một while-loop bằng for(2 byte), đặt gần như mọi thứ vào biểu thức của for(2 byte) và bằng cách thay thế foreachbằng join(3 byte). Cảm ơn Blackhole .
  • Đã lưu 3 byte bằng cách thay thế fgetsbằng stream_get_contentsCảm ơn bwoebi .
  • Đã lưu 5 byte bằng cách loại bỏ việc khởi tạo lại $cvì nó không còn cần thiết nữa $c .
  • Đã lưu 1 byte bằng cách xóa bộ sửa đổi mẫu mkhỏi Regex. Nhờ làm móng tay


1
@briantist Ôi trời, tôi hoàn toàn nhớ điều đó. : D Cảm ơn, giờ nó đã được sửa.
insertusernamehere

1
Tôi không thể chịu đựng được rằng Perl đánh bại PHP, vì vậy đừng quên: whilebị cấm khi chơi golf ( forthường ngắn hơn nhưng không bao giờ dài hơn) và để thực hiện một dòng mới, chỉ cần nhấn enter (1 byte thay vì 2 cho \n)! Đây là của bạn (chưa được kiểm tra) mã một chút golfed hơn (227 byte), với sự xuống dòng thay thế bằng :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
Tôi không có nghĩa là "bị cấm" là "trái với quy tắc", tôi chỉ có nghĩa là điều đó không hữu ích chút nào, vì một for-loop luôn tốt hơn một while-loop;).
Hố đen

1
@MichaelDibbets Thật ra tôi đã làm điều đó như được viết trong bản chỉnh sửa. Hừm. Hãy để tôi xem. Haha, tôi quên sao chép và đếm đoạn trích cuối cùng. Duh : D Những điều như thế xảy ra, nếu bạn cập nhật mã của mình trước khi ăn sáng. Cảm ơn đã chỉ ra điều đó.
insertusernamehere

14

Perl, 132 byte

Mã 155 byte + 17 cho -ln -MIO::Socket- 40 để liên tục yêu cầu URL

Như với câu trả lời của @ DigitalTrauma, regex phân tích cú pháp HTML, hãy cho tôi biết nếu điều đó không được chấp nhận. Không tiếp tục phân tích cú pháp URL nữa ... Tôi sẽ xem xét điều đó sau ... Gần với Bash! Xin chân thành cảm ơn @ Schwern đã tiết kiệm cho tôi 59 (!) Byte và @ skmrx để sửa lỗi để cho phép nhận phần thưởng!

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

Sử dụng

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

Tôi đã sửa một lỗi và rút ngắn mã bằng cách xóa yêu cầu khai báo $ h và $ p hoặc có đường dẫn mặc định. Nó cũng không còn yêu cầu theo dõi / trên máy chủ.
Schwern

1
Bây giờ chúng ta là người đánh bại. :)
Schwern

Tôi nghĩ rằng tôi đã làm cho đêm. :)
Schwern

Vì tập lệnh yêu cầu một URL khác thay vì thoát, bạn có thể yêu cầu thêm -40 byte
svsd

1
@DigitalTrauma bạn thực sự đúng! Tôi đã nhận được tiền thưởng nhờ skmrx sửa lỗi của tôi với '$ /' và tôi sẽ không ở gần bạn nếu không có Schwern!
Dom Hastings

13

PowerShell, 315 294 268 262 254 byte

355 334 308 302 294 - 40 cho lời nhắc

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

Yêu cầu PowerShell v5

Tất cả các kết thúc dòng (bao gồm cả các kết thúc được nhúng trong chuỗi) chỉ là các dòng mới \n(cảm ơn Blackhole ) được PowerShell hỗ trợ đầy đủ (nhưng nếu bạn đang thử nghiệm, hãy cẩn thận; ISE sử dụng \r\n).


4
+1 để thực hiện các nhiệm vụ quản trị viên máy chủ của tôi có vẻ hiệu quả hơn nhiều
so với

HTTP yêu cầu CRLF, không phải LF! [ HTTPSYNTAX ]
Bàn chải đánh răng

2
@tooth Brush Hà! Điểm lấy, nhưng điều khoản dung sai dường như có hiệu lực đầy đủ. Rõ ràng nhiệm vụ này là về những gì hoạt động và không đúng (nếu không chúng tôi sẽ phân tích HTML bằng regex và sử dụng các thư viện TCP cấp thấp thay vì các thư viện hiện có được kiểm tra tốt).
nghĩa tự do

1
@briantist greenbytes.de/tech/webdav/rfc7230.html#rfc.section.3.5 nói rằng "một người nhận CÓ THỂ nhận ra một LF là một đầu cuối dòng và bỏ qua mọi CR trước đó". Tôi đọc điều đó có nghĩa là hầu hết các máy chủ web sẽ thực hiện nó và câu hỏi chắc chắn không nói rằng nó phải tạo ra các yêu cầu chính xác GET . :)
Bàn chải đánh răng

8

Tập lệnh Groovy, 89 , 61 byte

Lặp lại để nhận tiền thưởng 101- 40 = 61

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

Chỉ với args, 89 byte

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

1
Groovy vượt xa mọi người. Như nó phải vậy.
một spaghetto

1
@quartata Nếu cứ như vậy, đây sẽ là lần đầu tiên , vì vậy ...;)
Geobits

11
"Chỉ cho phép các API TCP cấp thấp"
Chấn thương kỹ thuật số

Vâng, tôi sẽ đồng ý với @DigitalTrauma rằng điều này không sử dụng API TCP cấp thấp. Các quy tắc quy định rằng bạn phải tự tách máy chủ và đường dẫn.
TheDoctor

6

Bash (có thể gian lận nhưng dường như nằm trong quy tắc) 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

Cảm ơn kỹ thuật số.

Vì tôi không cần phải phân tách URL, nên điều này cũng hoạt động: 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
Tôi sẽ lập luận rằng việc sử dụng trình chuyển đổi html2txt trực tuyến này là một lỗ hổng tiêu chuẩn
Chấn thương kỹ thuật số

1
Đúng. Và tôi cũng sử dụng mèo để giải pháp của bạn an toàn.
philcolbourn

5

C 512 byte

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

Dựa vào mục nhập của tôi ở đây , Nó lấy địa chỉ web mà không có "https: //" hàng đầu. Nó sẽ không xử lý các <p>cặp lồng nhau một cách chính xác :(

Đã thử nghiệm rộng rãi trên www.w3.org/People/Berners-Lee/
Nó hoạt động khi được biên dịch với Apple LLVM version 6.1.0 (clang-602.0.53) / Target: x86_64-apple-darwin14.1.1
Nó có đủ hành vi không xác định mà nó có thể không hoạt động ở bất kỳ nơi nào khác.


Tôi đã đi xuống gần như cùng một bản nhạc (segfaults này khi được biên dịch bằng gcc), nhưng có thể có được dưới 400 byte trong C. Không chắc chắn về tiếng kêu, nhưng bạn không nên khai báo kiểu trả về của main. Thay vào đó, bạn cũng có thể loại bỏ bao gồm và "truy cập" các cấu trúc dưới dạng mảng số nguyên. Tôi cũng đã nhận được phản hồi với "GET /% s HTTP / 1.1 \ r \ n \ r \ n \", nhưng số dặm trên đó có thể thay đổi dựa trên trang web ...
Comi INTERN

5

Hồng ngọc, 118

Nguồn 147 byte; 11 byte ' -lprsocket'; -40 byte cho vòng lặp.

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

Ví dụ sử dụng:

$ 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

Tự động , 347 byte

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

Kiểm tra

Đầu vào:

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

Đầu ra:

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

Đầu vào:

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

Đầu ra:

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

Nhận xét

  • Không hỗ trợ các <p>thẻ lồng nhau
  • Chỉ hỗ trợ <p>thẻ (không phân biệt chữ hoa chữ thường), sẽ phá vỡ mọi định dạng thẻ khác
  • Panics Loops vô thời hạn khi có lỗi xảy ra

4

C #, 727 byte - 40 = 687 byte

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

Đó là một chút đào tạo nhưng chắc chắn đáng nhớ :)

Đây là một phiên bản chưa được chỉnh sử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;
        }
    }
}

Như bạn có thể thấy, có vấn đề rò rỉ bộ nhớ như một phần thưởng :)


Rò rỉ bộ nhớ ở đâu? Tôi thấy không có usingtuyên bố nào xung quanh các luồng nhưng điều đó không làm cho rò rỉ.
Gusdor

Bạn có thể cắt thêm một vài byte: input = input.trimStart ("http: //") sẽ thay thế mệnh đề "if" và bạn sẽ có thể sử dụng System.Text.Encoding.ASCII.GetBytes () mà không cần để lưu trữ nó trong asciiEncoding trước. Tôi nghĩ rằng bạn thậm chí còn đi ra với một "Hệ thống sử dụng;" dòng và loại bỏ một số ít "Hệ thống." s.
minnmass

3

JavaScript (NodeJS) - 187 166

s=require("net").connect(80,p=process.argv[2],_=>s.write("GET / HTTP/1.0\nHost: "+p+"\n\n")&s.on("data",d=>(d+"").replace(/<p>([^]+?)<\/p>/g,(_,g)=>console.log(g))));

187:

s=require("net").connect(80,p=process.argv[2],_=>s.write("GET / HTTP/1.1\nHost: "+p+"\nConnection: close\n\n")&s.on("data",d=>(d+"").replace(/<p>([^]+?)<\/p>/gm,(_,g)=>console.log(g))));

Sử dụng:

node file.js www.example.com

Hoặc được định dạng

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
Hãy cẩn thận: điều này sẽ hoạt động cho các trang nhỏ - các trang lớn hơn phát ra nhiều sự kiện dữ liệu.
Benjamin Gruenbaum

3

Python 2 - 212 209 byte

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

Bạn có thể lưu hai byte bằng cách tước khoảng trắng sau dấu hai chấm trên while h:và trước print g.
Skyler

Và một byte khác với 'GET /%s HTTP/1.1\nHost:%s\n\n'.
Cees Timmerman

3

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

Phiên bản nén và lặp của câu trả lời của 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))

Thí dụ:

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

Thực tế hữu ích là thế này:

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

Thí dụ:

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 byte

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

Chơi golf xuống, nhưng đây là một phiên bản khó tha thứ hơn, cần địa chỉ web mà không có http://ngay từ đầu. Và nếu bạn muốn truy cập thư mục gốc, bạn phải kết thúc địa chỉ bằng a /. Hơn nữa, các <p>thẻ phải được viết thường.

Phiên bản trước của tôi thực sự không xử lý các dòng chứa </p><p>chính xác. Điều này hiện đã được sửa.

Đầu ra cho đầu vào 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>

Vẫn không hoạt động với Wikipedia. Tôi nghĩ lý do là Wikipedia sử dụng httpscho mọi thứ. Nhưng tôi không biết.

Phiên bản sau đây dễ tha thứ hơn một chút với đầu vào và nó cũng có thể xử lý các thẻ chữ hoa.

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

Tôi không chắc chắn về "Connection:close"dòng. Dường như không bắt buộc. Tôi không thể tìm thấy một ví dụ có thể hoạt động khác đi hoặc không có nó.


1

Quyền hạn (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 (không cần 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 "")

chỉnh sửa * cũng không khó để ghi nhớ ^^


-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
Chào mừng bạn đến với Câu đố lập trình & Code Golf! Thật không may, trình này là không hợp lệ. Câu hỏi chỉ cho phép các API TCP cấp thấp, vì vậy bạn không thể sử dụng InputStreamReader.
Dennis

1
Oh tôi rất xin lỗi và cảm ơn bạn đã chỉ nó. sẽ làm tốt hơn trong câu trả lời tiếp theo
Shalika Ashan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.