getlinks.pl.in 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #!@PERL@
  2. #
  3. # getlinks.pl
  4. #
  5. # This script extracts all links from a HTML page, compares them to a pattern
  6. # entered on the command line and then downloads matching links into the
  7. # target dir (also specified on the command line).
  8. #
  9. # Written to use 'curl' for URL fetching, uses the source file names in the
  10. # target directory.
  11. #
  12. # Author: Daniel Stenberg <Daniel.Stenberg@sth.frontec.se>
  13. # Version: 0.1 Oct 7, 1998
  14. #
  15. # HISTORY
  16. #
  17. # 0.1 - Created now!
  18. #
  19. $in="";
  20. argv:
  21. if($ARGV[0] eq "-v" ) {
  22. $verbose = 1;
  23. shift @ARGV;
  24. goto argv;
  25. }
  26. if($ARGV[0] eq "-d" ) {
  27. $display = 1;
  28. shift @ARGV;
  29. goto argv;
  30. }
  31. elsif($ARGV[0] eq "-h" ) {
  32. $help = 1;
  33. shift @ARGV;
  34. goto argv;
  35. }
  36. $geturl = $ARGV[0];
  37. $getdir = $ARGV[1];
  38. $getregex = $ARGV[2];
  39. if(($geturl eq "") ||
  40. (($getdir eq "") && !$display) ||
  41. $help) {
  42. print "Usage: $0 [-hv] <full source URL> <target dir> [regex]\n",
  43. " Use a traling slash for directory URLs!\n",
  44. " Use \"quotes\" around the regex!\n",
  45. " -h This help text\n",
  46. " -d Display matches only instead of downloading\n",
  47. " -v Verbose mode\n";
  48. exit;
  49. }
  50. # change to target directory:
  51. chdir $getdir ||
  52. die "couldn't cd into $getdir";
  53. # This is necessary from where I tried this:
  54. #$proxy =" -x 194.237.142.41:80";
  55. # linkchecker, URL will be appended to the right of this command line
  56. # this is the one using HEAD:
  57. $linkcheck = "curl -s -m 20 -I$proxy";
  58. # as a second attempt, this will be used. This is not using HEAD but will
  59. # get the whole frigging document!
  60. $linkcheckfull = "curl -s -m 20 -i$proxy";
  61. # htmlget, URL will be appended to the right of this command line
  62. $htmlget = "curl -s$proxy";
  63. # urlget, URL will be appended to the right of this command line
  64. # this stores the file with the remote file name in the current dir
  65. $urlget = "curl -O -s$proxy";
  66. # Parse the input URL and split it into the relevant parts:
  67. sub SplitURL {
  68. my $inurl = $_[0];
  69. if($inurl=~ /^([^:]+):\/\/([^\/]*)\/(.*)\/(.*)/ ) {
  70. $getprotocol = $1;
  71. $getserver = $2;
  72. $getpath = $3;
  73. $getdocument = $4;
  74. }
  75. elsif ($inurl=~ /^([^:]+):\/\/([^\/]*)\/(.*)/ ) {
  76. $getprotocol = $1;
  77. $getserver = $2;
  78. $getpath = $3;
  79. $getdocument = "";
  80. if($getpath !~ /\//) {
  81. $getpath ="";
  82. $getdocument = $3;
  83. }
  84. }
  85. elsif ($inurl=~ /^([^:]+):\/\/(.*)/ ) {
  86. $getprotocol = $1;
  87. $getserver = $2;
  88. $getpath = "";
  89. $getdocument = "";
  90. }
  91. else {
  92. print "Couldn't parse the specified URL, retry please!\n";
  93. exit;
  94. }
  95. }
  96. &SplitURL($geturl);
  97. #print "protocol = $getprotocol\n";
  98. #print "server = $getserver\n";
  99. #print "path = $getpath\n";
  100. #print "document = $getdocument\n";
  101. #exit;
  102. if(!$usestdin) {
  103. open(HEADGET, "$linkcheck $geturl|") ||
  104. die "Couldn't get web page for some reason";
  105. headget:
  106. while(<HEADGET>) {
  107. # print $_;
  108. if($_ =~ /HTTP\/.*3\d\d /) {
  109. $pagemoved=1;
  110. }
  111. elsif($pagemoved &&
  112. ($_ =~ /^Location: (.*)/)) {
  113. $geturl = $1;
  114. &SplitURL($geturl);
  115. $pagemoved++;
  116. last headget;
  117. }
  118. }
  119. close(HEADGET);
  120. if($pagemoved == 1) {
  121. print "Page is moved but we don't know where. Did you forget the ",
  122. "traling slash?\n";
  123. exit;
  124. }
  125. open(WEBGET, "$htmlget $geturl|") ||
  126. die "Couldn't get web page for some reason";
  127. while(<WEBGET>) {
  128. $line = $_;
  129. push @indoc, $line;
  130. $line=~ s/\n//g;
  131. $line=~ s/\r//g;
  132. # print $line."\n";
  133. $in=$in.$line;
  134. }
  135. close(WEBGET);
  136. }
  137. else {
  138. while(<STDIN>) {
  139. $line = $_;
  140. push @indoc, $line;
  141. $line=~ s/\n//g;
  142. $line=~ s/\r//g;
  143. $in=$in.$line;
  144. }
  145. }
  146. sub GetLinks {
  147. my $in = $_[0];
  148. my @result;
  149. getlinkloop:
  150. while($in =~ /[^<]*(<[^>]+>)/g ) {
  151. # we have a tag in $1
  152. $tag = $1;
  153. if($tag =~ /^<!--/) {
  154. # this is a comment tag, ignore it
  155. }
  156. else {
  157. if($tag =~ /(src|href|background|archive) *= *(\"[^\"]\"|[^ )>]*)/i) {
  158. $url=$2;
  159. if($url =~ /^\"(.*)\"$/) {
  160. # this was a "string" now $1 has removed the quotes:
  161. $url=$1;
  162. }
  163. $url =~ s/([^\#]*)\#.*/$1/g;
  164. if($url eq "") {
  165. # if the link was nothing than a #-link it may now have
  166. # been emptied completely so then we skip the rest
  167. next getlinkloop;
  168. }
  169. if($done{$url}) {
  170. # if this url already is done, do next
  171. $done{$url}++;
  172. next getlinkloop;
  173. }
  174. $done{$url} = 1; # this is "done"
  175. push @result, $url;
  176. if($tag =~ /< *([^ ]+)/) {
  177. # print "TAG: $1\n";
  178. $tagtype{$url}=$1;
  179. }
  180. }
  181. }
  182. }
  183. return @result;
  184. }
  185. @links = &GetLinks($in);
  186. linkloop:
  187. for(@links) {
  188. $url = $_;
  189. if($url =~ /^([^:]+):/) {
  190. $link = $url;
  191. }
  192. else {
  193. # this is an absolute link on the same server:
  194. if($url =~ /^\//) {
  195. # from root
  196. $link = "$getprotocol://$getserver$url";
  197. }
  198. else {
  199. # from the scanned page's dir
  200. $nyurl=$url;
  201. if(length($getpath) &&
  202. ($getpath !~ /\/$/) &&
  203. ($nyurl !~ /^\//)) {
  204. # lacks ending slash, add one to the document part:
  205. $nyurl = "/".$nyurl;
  206. }
  207. $link = "$getprotocol://$getserver/$getpath$nyurl";
  208. }
  209. }
  210. if($link =~ /$getregex/) {
  211. if($display) {
  212. print "$link\n";
  213. }
  214. else {
  215. if($verbose) {
  216. print "Gets $link\n";
  217. }
  218. print `$urlget $link`;
  219. }
  220. }
  221. }