Как я могу заменить ISBN идентификатором Google Книги в файле MARC, используя Perl?
У меня есть файл с некоторыми данными книги в формате MARC, некоторые строки которого являются номерами ISBN. Я хотел бы заменить эти строки идентификатором Google Books этого ISBN, если он существует. Вот код, который до сих пор просто удаляет строки:
perl -pe "s#ISBN(.*)#$(wget --output-document=- --quiet --user-agent=Mozilla/5.0 \"http://books.google.com/books?jscmd=viewapi&bibkeys=\1\")#mg" < 5-${file} > 6-${file}
PS: Google немного не уверен в использовании автоматических инструментов: API данных о книгах рекомендует использовать такие инструменты, как curl / wget, но нет никаких инструкций о том, как избежать блокировки при использовании таких инструментов. Я также почти уверен, что увидел в ToS пункт, в котором говорится, что пользователи не могут отправлять автоматические запросы, но я не могу найти его снова. Это обсуждается на их форуме.
2 ответа
Я думаю, что OP находится на правильном пути и может использовать для этого однострочник, и ему просто нужно заменить синтаксис в стиле bash на правильный синтаксис Perl. Я думаю, что это будет работать (добавлены новые строки для удобства чтения):
perl -pe 's#ISBN(\w+)#qx(wget --output-document=-
--quiet --user-agent=Mozilla/5.0
"http://books.google.com/books\\?jscmd=viewapi\\&bibkeys=$1")#ge' \
< 5-${file} > 6-${file}
Вы должны убежать (редактировать: двойное побег, кажется, работает) $
или же &
символы в URL.
Причина, по которой вам приходится лгать о пользовательском агенте, заключается в том, что вы нарушаете Условия использования Google: не делайте этого.
Вместо этого используйте API поиска книг Google.
Приведенный ниже код немного затруднен из-за моего недостаточного знакомства с такими модулями, как XML:: Atom, Data:: Feed, WWW:: OpenSearch. Тем не менее, это должно обеспечить хорошую отправную точку.
#!/usr/bin/perl
use strict;
use warnings;
use Business::ISBN qw( valid_isbn_checksum );
use LWP::Simple;
use XML::Simple;
while ( <> ) {
s/ISBN:([0-9]+)/'Google Books ID:' . get_google_id_for_isbn($1)/ge;
print;
}
use Carp;
sub make_google_books_query {
sprintf 'http://books.google.com/books/feeds/volumes?q=isbn:%s', $_[0];
}
sub get_google_id_for_isbn {
my ($isbn) = @_;
my $google_id = eval {
defined(valid_isbn_checksum $isbn)
or croak "Invalid ISBN: $isbn";
my $query = make_google_books_query($isbn);
my $xml = get $query;
defined($xml)
or croak "No response to <$query>";
my $data = XMLin($xml, ForceArray => 1);
my @ids = @{ $data->{entry}[0]{'dc:identifier'} };
unless ("ISBN:$isbn" eq $ids[1]
or "ISBN:$isbn" eq $ids[2] ) {
croak "Invalid search results: '@ids'";
}
$ids[0];
};
defined($google_id) ? $google_id : '';
}
Учитывая текстовый файл t.txt
содержащий:
ISBN: 0060930314 ISBN: 9780596520106
это выводит:
Идентификатор Google Книг:ioXFqlzsmK8C Идентификатор Google Книг:lNVHi3TunxsC