Come posso sostituire il codice ISBN con il Google Books ID in un file MARC, utilizzando Perl?

StackOverflow https://stackoverflow.com/questions/1667926

  •  13-09-2019
  •  | 
  •  

Domanda

Ho un file con alcuni dati del libro in formato MARC , di cui alcune linee sono codici ISBN. Mi piacerebbe sostituire queste linee con l'ID di Google Libri che ISBN, se esiste. Ecco il codice finora, che appena finisce la rimozione delle linee:

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 sono un po 'confusi su l'uso di strumenti automatizzati: Libri dati API raccomanda strumenti come ricciolo / wget, ma non ci sono le istruzioni su come evitare di essere bloccato quando si utilizzano tali strumenti. Sono anche abbastanza sicuro che ho visto una clausola in un ToS dire gli utenti non possono inviare query automatizzate, ma non riesco a trovare di nuovo. Questo è discusso nel loro forum.

È stato utile?

Soluzione

Credo che il PO è sulla strada giusta e potrebbe utilizzare un one-liner per questo, e solo bisogno di sostituire alcuni sintassi bash in stile con la sintassi di Perl corretta. Penso che questo dovrebbe funzionare (a capo aggiunto per migliorare la leggibilità):

    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}

Dovete fuggire. (Edit: doppio escape sembra funzionare) le $ o & caratteri nell'URL

Altri suggerimenti

La ragione si finisce per dover mentire circa l'user agent è perché si stanno violando TOS di Google: Non farlo

.

Al contrario, utilizzare il Google Book Search API .

Il codice qui sotto è un po 'ostacolato dalla mia mancanza di familiarità con moduli quali XML :: atomo , Data :: feed , WWW :: OpenSearch . Tuttavia, dovrebbe fornire un buon punto di partenza.

#!/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 : '';
}

Dato un t.txt file di testo contenente:

ISBN:0060930314
ISBN:9780596520106

emette:

Google Books ID:ioXFqlzsmK8C
Google Books ID:lNVHi3TunxsC
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top