Алейкин ВВ Анализ способов доступа к электронным публикациям
Алейкин Владислав Валерьевич
 

Алейкин Владислав Валерьевич


Специальность:
Программное обеспечение автоматизированных систем
Тема выпускной работы:
Распределенная система распознавания текстовой информации
Руководитель:
доцент, к.т.н. Ладыженский Юрий Валентинович




Индивидуальный раздел

Анализ способов доступа к электронным публикациям
специальной базы данных
http://www3.interscience.wiley.com

    На сайте http://www3.interscience.wiley.com расположено многочисленное количество статей по различным направлениям современной науки. Сайт предоставляет платный доступ ко множеству журналов, содержащих много интересной информации по развитию науки и не только. Подробную информацию о библиотеке Interscience можно узнать здесь. Единственным недостатком является то, что сайт «платный». Но есть и положительный момент: ДонНТУ предоставлялся бесплатный доступ ко всем журналам, правда, на ограниченный срок.

Сайт interscience.wiley.com


    Скачать интересующую меня информацию можно было без проблем, но только через сеть ДонНТУ, но что если через год или два мне опять понадобится один из таких журналов? Хоть цена и не такая большая за журнал, но зачем платить, когда можно сейчас скачать все и сохранить себе на диск, а потом уже разбираться, что нужно, а что нет.

Приступим

    Сначала нужно определить, что же собой представляет сайт и как с него качать. Вводим в поисковике сайта любой запрос и видим, что журнал разбивается на год, в каждом году несколько выпусков, в каждом выпуске несколько статей (например, http://www3.interscience.wiley.com/journal/117994078/issueyear?year=2008 ). В целом достаточно обычный механизм обращения к требуемым документам.
    Здесь можно выделить первый способ работы со специальной базой данных – ручное «клацанье» по ссылкам. Вот по этой ссылке очень хорошо и подробно описала магистр Сычева Екатерина. Но скачивать по одной статье за раз – это занятие нудное, странно, что разработчики об этом не подумали. А если нужны все журналы за год - здесь дела совсем плачевны. Но все так плохо, если Вы не программист, ведь программисту все под силу.
    Если обратить внимание на самый первый журнал в году, то можно увидеть, что его можно скачать бесплатно из любой сети, не только из ДонНТУ. Скорей всего это сделано ради привлечения клиентов. Эта особенность мне очень понравилась, так как не было достаточно времени разбираться в одной из аудиторий ДонНТУ. Да и тестировать свое будущее приложение будет на чем.

Программная часть

    Я, если честно, с HTTP протоколом знаком не сильно близко, всего несколько раз программировал под него, да и было это давно. Сразу, что пришло в голову – автоматизировать действия, выполняемые при скачивании документа через javascript. Да, это очень легкий способ, не требующих значительных усилий в программировании, но у него есть и отрицательные стороны:
    – «корявость» - каждый раз при переходе по странице будет перегружаться страница;
    – антивирусы будут ругать на файлы, содержащие скрипт сохранения файла на диск.
    От этого метода я отказался сразу. Поэтому единственный хороший вариант – написание собственного мини-браузера, осуществляющего только несколько действий: загрузку страницы, нахождение ссылок, сохранение требуемой на диск.
    Я решил написать свой «браузер» на языке C++ с использованием MFC, он мне очень близок и я лучше всего разбираюсь в нем.
    Первое что потребуется – это подключение файла afxinet.h в проект. В данной программе основными являются классы, объекты которых создаются так:

     CInternetSession *m_pSession;
     CHttpConnection * m_pServer;
     CHttpFile * m_pFile=NULL;

    Для установления соединения необходимо использовать следующую функцию GetHttpConnection. Входными параметрами являются адрес и порт сервера, а выходными – объект CHttpConnection.
    На следующем этапе следует запросить необходимую страницу. Для этого сначала нужно вызвать OpenRequest – для предварительного формирования запроса, с указанием требуемой страницы, затем добавить дополнительную информацию к HTTP-заголовку с помощью CHttpFile::AddRequestHeaders и затем послать сформированный запрос на сервер CHttpFile::SendRequest.
    Если все было успешно, то с помощью функции CHttpFile::Read можно прочесть страницу в буфер и проанализировать на необходимую информацию. Успешно или нет прошел запрос можно узнать с помощью функции CHttpFile::QueryInfo. HTTP-запрос должен вернуть код 200, что свидетельствует об успешности операции.
    Когда я первый раз проделал описанные шаги, я получил код возврата 302, этот код возврата означает, что страница была перемещена, а в качестве содержимого я получил страницу, формируемую сервером. В ней говорилось, что мне необходимо включить cookie. И действительно, когда я создавал объект CInternetSession, я его создал с флагом игнорирования cookie. Он не принимал и не посылал необходимые для работы «плюшки». Убрав этот флаг – страница полностью загрузилась, и код возврата был 200.
    Теперь у нас есть функция, которая загружает указанную страницу и сохраняет ее в буфер. Но как было указано в самом начале, чтобы добраться до прямой ссылки на файл необходимо перейти еще по двум ссылкам. Поэтому с первой страницы необходимо выбрать нужные ссылки, отвечающие за журналы указанного года, со второй – ссылки, отвечающие за статьи журнала. Написать функцию поиска нужных ссылок достаточно просто, так как такие ссылки отличаются от других. Для первой страницы в ссылках присутствуют слова «journal» и «issue», для второй – слово «PDFSTART». Используя по циклу на каждую страницу и функцию поиска нужных ссылок можно обойти и скачать все статьи за указанный год определенного журнала.
    В целом программа загрузки документов уже готова, но есть один момент с cookie. Так как я заходил без авторизации, то я автоматически принимал cookie и устанавливал их сессии. При использовании на бесплатных статьях такой метод предоставлял мне скачивание документов, но вот при проверке на платных статьях корректная авторизация требовалась однозначна. Поэтому необходимо выставить cookie для соединения следующим образом:

m_pSession->SetCookie(_T("http://download.interscience.wiley.com"), _T("PhoLIVEServerID"), _T("1026"));
m_pSession->SetCookie(_T("http://download.interscience.wiley.com"), _T("RSID"), _T("13479e2af3db3694a184a9f039239cf5f9d7b8e0"));
m_pSession->SetCookie(_T("http://download.interscience.wiley.com"), _T("SID"), _T("1:20x5D08E7DF4669191D9ED3B8E637BCC52C"));
m_pSession->SetCookie(_T("http://download.interscience.wiley.com"), _T("CID"), _T("128639074"));
m_pSession->SetCookie(_T("http://download.interscience.wiley.com"), _T("TEST_COOKIE"), _T("1"));

    Вы можете узнать, какие cookie требует сайт при скачивании с помощью просмотра списка cookie в браузере или с «ручным принятием cookie». Второй метод более хорош, так как некоторые cookie второстепенны, и не всегда важны при скачивании документов.

    Вот экранная форма полученного приложения


Project screen


Заключение

     Хочу сказать, что лучше всего реализовывать такой модуль в виде библиотеки, чтобы потом его использовать в других программах. Никогда не знаешь, что может пригодится в будущем.
     На этом можно закончить описание создание программы автоматизированного скачивания информации. Программа работает стабильно, сохраняет все требуемые документы.
     В качестве заключения хочу сказать, что закон подлости все такие есть – после написания программы оказалось, что бесплатный доступ к базе данных из сети ДонНТУ был закрыт. Начал писать программу я за день до окончания срока предоставления бесплатного доступа университету и скачать базу полностью я не успел. Может, еще будет предоставляться доступ к данному ресурсу и тогда моя программа точно пригодится. Но зато было интересно выполнить такое задание.

     Немного позже я поближе познакомился с HTTP, но с помощью WINHTTP. Работает данная библиотека аналогичным способом, но более удобная, так как весь нужный «контент» уже заранее раскладывается по полочкам в объекте и писать дополнительный «парсер» htm кода нет необходимости.

 


     Исполняемый файл: HTTP Client.exe
     Проект: HTTP Client.rar

 

PS: Запуск из Delphi.
     Если Вы написали библиотеку и ее нужно использовать в программе на Delphi, то следующее будет полезным.
     Для вызова функций из библиотеки необходимо:
     1) объявить прототип функции
var COM_Init: function(): short; stdcall;
     2) Загрузить библиотеку
DllHandle := LoadLibrary('GComS2K120.dll'); if(DllHandle = 0) then ShowMessage('GComS2K120.dll was not loaded');
     3) Динамически подгрузить нужную функцию
@COM_Init := GetProcAddress(DllHandle, '?COM_Init@@YAFXZ');
     4) Вызвать функцию
result := COM_Init();


     Важные особенности:
     – прототип функции должен быть объявлен с директивой stdcall;
     – количество передаваемых и возвращаемых байт в каждой функции должно быть как и в С++;
     – объявление С++ перечислений (enum) следует заменить на массив переменных типа integer. Начать нумерацию с 0. При передачи использовать этот созданный массив. Такие действия приходится делать из-за того, что размер перечислений в С++ – 4бата, а в Delphi – 1байт. Если функция возвращает перечисление, то оно будет записываться в тип integer, для логического сравнения требуется сделать специальный механизм сравнения целого с символьной константой (для восприятия при программировании, возможно есть более легкий путь это сделать);
     – если в функции встречается параметр описанный как type &BaudRate, то в Delphi его следует заменить на var BaudRate: type. ‘Var’ аналогичен ‘&’.