Загрузка ссылок с LinuxToday и оглавления выпуска Linux Gazette с помощью Python (и Perl)

  Автор: © Mark Nielsen
Перевод: © Владимир Меренков.


 

Содержание

  1. Введение
  2. Python-скрипт
  3. Установка задания для cron
  4. Мой Perl-скрипт для скачивания оглавления выпускаLinux Gazette
  5. Мой Perl-скрипт для скачивания еженедельных новостей Debian
  6. Заключение
  7. Ссылки

Введение

Я хотел добавить ссылки с Linux Today на мой вэбсайт GNUJobs.com просто так, для забавы. Позже я хочу добавить заголовки с других вэбсайтов и, может быть, последний выпуск LG. У меня был выбор - что ипользовать: Python или Perl. Я остановился на Python, потому что я долгое время использовал этот язык в математических проектах, и он доказал свою полезность. Теперь я хочу сделать для себя привычкой использование Python. Для меня становится легче программировать на Python, чем на Perl. В будущем, я также собираюсь использовать разбиение процесса на потоки (threads) для одновременного скачивания большого количества вэбстраниц одновременно, что Python делает очень хорошо. К тому же, я использую Python сейчас, так как знаю, что буду использовать его и потом.

И Perl, и Python позволят Вам загрузить вэбстранички из интернета. Вы можете также делать многое другое, нежели просто скачивать страницы. В вашем распоряжении инструменты для работы с ftp, gopher и другими сервисами. Загрузка вэб-страницы - всего лишь пример того, что можно сделать с помощью этих языков.

В данном случае от языка программирования требует следующее:

  • Загрузить вэб-страницу
  • Сделать корректный разбор данных для переформатирования
  • Переформатировать данные
  • Заменить старый файл новым, если только он содержит достоверные данные

Эта статья обещает быть не слишком длинной. Описываемый Python-код подробно откомментирован.

Python-скрипт

Если Вы хотите включить вывод этого скрипта непосредственно в вэбстраницу, тогда Вы можете использовать модуль Server-Side Include (SSI) сервера Apache, и в Вашей вэбстранице использовать команду типа:
<!--#include virtual="/lthead.html" -->
С помощью различных языков программирования (таких как PHP, Perl ASP, Perl Mason и т.д.) также можно включать файлы в вэбстраницу.

Подразумевается, что Вы используете операционную систему GNU/Linux. Я, также, использую Python версии 1.5.2, которая не является самой последней. Чтобы сделать скрипт исполняемым, Вам придется выполнить команду

chmod 755 LinuxToday.py

(Файл http://linuxtoday.com/backend/lthead.txt состоит из трехстрочных записей разделенных двойным амперсандом. Первая строка в записи - заголовок, вторая - линк, третья - дата. прим. пер.)

[Текстовая версия этого листинга.]

#!/usr/bin/python

# Одна очевидная вещь, которую нужно сделать - применить проверку для скачиваемого url,
# скачанная информация должна содержать по крайней мере одно вхождение, 
# и у нас должна быть возможность создать новый файл.
# Это будет сделано позже.

 ### импортировать модули web, string, re, os 
import urllib, string, re, os

 ### Определить название для нового HTML файла, который мы создаем, и где взять информацию
Download_Location = "/tmp/lthead.html"
Url = "http://linuxtoday.com/backend/lthead.txt"

#-----------------------------------------------------------
  ### Создать web объект с Url
LinuxToday = urllib.urlopen( Url )
 ### Собрать всю информацию в массив (если много, замените на считывание по одной строке)
Text_Array =  LinuxToday.readlines()

New_File  = open(Download_Location + "_new", 'w');
New_File.write("<ul>\n") 
  ### Установить значение по умолчанию недействительным
Valid = 0
  ### Записать число допустимых вхождений
Entry_No = 0;
Entry_Valid = 0
  ### Установить значения по умолчанию
Date = ""
Link = ""
Header = ""
Count = 0
  ### Создать шаблон соответствия выражению
Match = re.compile ("^\&\&")

  ### Добавить && , чтобы удостовериться, что мы анализируем последнее вхождение
Text_Array.append('&&')
  ### Для каждой строки сделать
for Line in Text_Array :
    ### Если есть &&, начать опять с пустых значений, добавить посл. вхождение
  if Match.search(Line) :
      ### Если текущее вхождение допустимо и не является первым 
    if (Entry_No > 1) and (Entry_Valid > 0) :
	### Одна вещь, которую Perl делает лучше Python'а - выполнение команды print.
	### Мне не нравится как "печатает" Python (никакой интерполяции переменных).
      New_File.write('<li> <a href="' + Link + '">' + Header + '</a>. ' + Date + "</li>\n")
      ## "Опустошить" значения переменных.
    Header = ""; Link = ""; Date = ""; Entry_Valid = 0
    Count = 0 
    
    ### Стереть пробелы в конце строки
  Line = string.rstrip(Line)

    ### Если счетчик равен 1 то заголовок, 2 - линк, 3 -  дата
  if Count == 1:    Header = Line
  elif Count == 2:  Link = Line
  elif Count == 3:  
    Date = Line
      ### Если все поля заполнены, мы имеем допустимое вхождение
    if  (Header != "") or (Link != "") or (Date != "") :
      Entry_No = Entry_No + 1
      Entry_Valid = 1  

    ### Добавить 1 к Count
  Count = Count + 1

New_File.write("</ul>\n")

New_File.close()

  ### Если у нас допустимые вхождения переместим файл в реальное место расположения
if Entry_No > 0 :
    ### Мы могли бы сделать просто:
    ### os.rename(Download_Location + "_new", Download_Location)
    ### Но здесь показано как сделать то же с помощью внешней команды.
  Command = "mv " + Download_Location + "_new " + Download_Location
  os.system( Command )

Cron скрипт для еженочного запуска программы

Не самый лучший crontab файл, но работать будет.
#/bin/sh

### Crontab file
### Назвать файл "Crontab" и запускать его командой "crontab Crontab"

  ### Загружать каждые 2 часа
*/2 * * * *   /www/Cron/LinuxToday.py >> /www/Cron/out  2>&1  

Мой Perl-скрипт для скачивания оглавленияLinux Gazette

Только для того, чтобы вы могли сравнить Python с языком Perl, я создал Perl-скрипт, который скачивает оглавление LG самой последней редакции. [Текстовая версия этого листинга.]
#!/usr/bin/perl
# Copyright Mark Nielsen January 20001
# Copyrighted under the GPL license.

# Я горжусь этим скриптом.
# Я написал его из ничего и при тестировании обнаружил только 2 незначительные ошибки.

system ("lynx --source http://www.linuxgazette.com/ftpfiles.txt > /tmp/List.txt");

  ### Открыть вэбстраницу которую мы загрузили и поместить в массив.
open(FILE,'/tmp/List.txt'); my @Lines = <FILE>; close FILE; 
  ### Отфильтровать строки, которые не содержат "волшебных" символов.
my @Lines = grep(($_ =~ /lg\-issue/) || ($_ =~ /\.tar\.gz/), @Lines );

my @Numbers = ();
foreach my $Line (@Lines)
  {
    ## Отбросить ненужное слева
  my ($Junk,$Good) = split(/lg\-issue/,$Line,2);
    ## Отбросить ненужное справа
  ($Good,$Junk) = split(/\.tar\.gz/,$Good,2);
    ## Если это число большее единицы, сохранить его
  if ($Good > 0) {push (@Numbers,$Good);}
  }

   ### Отсортировать числа начиная с большего
@Numbers = sort {$a<=>$b} @Numbers;
my $Highest = pop @Numbers;
   ## Создать url, который мы собираемся скачать
my $Url = "http://www.linuxgazette.com/issue$Highest/index.html"; 
   ## Скачать его
system ("lynx --source $Url > /tmp/LG_index.html");

   ### Открыть индекс.
open(FILE,"/tmp/LG_index.html"); my @Lines = <FILE>; close FILE;
   ### Выделить части между началом и концом оглавления.
my @TOC = ();
my $Count = 0;
my $Start = '<!-- *** BEGIN toc *** -->';
my $End = '<!-- *** END toc *** -->';
foreach my $Line (@Lines) 
  {
  if ($Line =~ /\Q$End\E/) {$Count = 2;}
  if ($Count == 1) {push(@TOC, $Line);}
  if ($Line =~ /\Q$Start\E/) {$Count = 1;}
  }

  ### Переделать все линки, чтобы они показывали на Linux Gazette
my $Relink = "http://www.linuxgazette.com/issue$Highest/";
grep($_ =~ s/HREF\=\"/HREF\=\"$Relink/g, @TOC);

  ### Сохранить вывод
open(FILE,">/tmp/TOC.html"); print FILE @TOC; close FILE;

  ### Все!

Мой Perl скрипт для скачивания еженедельных новостей Debian

Я люблю следить за еженедельными новостями Debian, так что я написал и этот скрипт. Одно плохо в программировании, когда ты по-настоящему хорошо программируешь на одном языке, трудно переключиться на другой язык программирования. Эти два скрипта на Perl я написал, не заглядывая ни в какой другой код. Python код отнял у меня время, потому что я еще не привык к этому языку. [Text version of this listing.]
#!/usr/bin/perl
# Copyright Mark Nielsen January 2001
# Copyright under the GPL license.

system ("lynx --source http://www.debian.org/News/weekly/index.html > /tmp/List2.txt");

  ### скачанную вэбстраницу поместить в массив.
open(FILE,'/tmp/List2.txt'); my @Lines = <FILE>; close FILE; 
   ### Выделить части между началом и концом TOC.
my @TOC = ();
my $Count = 0;
my $Start = 'Recent issues of Debian Weekly News';
my $End = '</p>';
foreach my $Line (@Lines) 
  {
  if (($Line =~ /\Q$End\E/i) && ($Count > 0)) {$Count = 2;}
  if ($Count == 1) {push(@TOC, $Line);}
  if ($Line =~ /^\Q$Start\E/i) {$Count = 1;}
  }

  ### Переделать все линки, чтобы они показывали на DWN
my $Relink = "http://www.debian.org/News/weekly/";
grep($_ =~ s/HREF\=\"/HREF\=\"$Relink/ig, @TOC);
grep($_ =~ s/\"\>/\" target=_external\>/ig, @TOC);

  ### Сохранить вывод
open(FILE,">/tmp/D.html"); print FILE @TOC; close FILE;

  ### Все!

Заключение

Фактически, скрипт на Python'е является гораздо более полным решением, чем необходимо. Причиной того, почему я сделал его более длинным является то, что я ввел различные модули и сделал его более гибким на случай, если формат LinuxToday когда-нибудь изменится. Единственное, чего не хватают скрипту, так это обнаружение ошибок при невозможности скачать страницу, открыть новый файл или переименовать его. Обратите внимание также на модули обработки регулярных выражений в Python, так как они были изменены в последних версиях для увеличения эффективности и поддержки Unicode.

Python как язык программирования - рулез. Я нашел очень легкими в использовании модули Python. Похоже на то, что Python модуль для обработки вэбстраниц легче в использовании, чем модуль LWP в Perl. Так как Python - язык с большими возможностями, у меня есть план создания программы, которая будет скачивать одновременно множество вэбстраниц, используя способность многопоточности Python'а.

Ссылки

  1. LinuxToday's links
  2. Python's urllib module
  3. Original site for this article (в случае изменения документа, обновления появятся здесь)

 


Copyright © 2001, Mark Nielsen.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 63 of Linux Gazette, Mid-February (EXTRA) 2001

Вернуться на главную страницу