[JAVA] Erstellen Sie eine Datenbank aller Bücher, die im letzten Jahrhundert in Japan im Umlauf waren

0. Einführung (Zielleser usw.)

Es ist ein Angeltitel. Es tut mir Leid. Tatsächlich werden wir eine Datenbank aller ** "699 TV / Radio" -Bücher erstellen, die im letzten Jahrhundert in Japan im Umlauf waren. Außerdem ** Da ein großer Teil des automatischen Zugriffs auf den Server der National Diet Library erfolgt, geschieht dies bitte auf eigenes Risiko **.

Zielgruppe

1. Experimentieren

Wenn Sie eine detaillierte Suche mit der Nationalbibliothek durchführen und nur mit dem Klassifizierungscode "699" suchen, Sie können von 1925 bis 2020 im Fernsehen und im Radio nach allen Büchern suchen. Leider können in einer einzigen Suche nur die 500 besten Ergebnisse angezeigt werden. (Der 501. und nachfolgende Artikel werden überhaupt nicht in den Suchergebnissen angezeigt.) Sie können Ihre Suche auch nach Veröffentlichungsjahr verfeinern. In jedem Jahr von 1925 bis 2020 betrug die Anzahl der Ergebnisse jedoch nicht mehr als 500 (in einem Jahr). Wenn Sie also jedes Jahr eine Suche durchführen und die Ergebnisse abrufen, dauert es einige Zeit, aber versuchen wir, alle Ergebnisse anzuzeigen.

1-1. Experiment 1 ndl Crawler Design

Ein Crawler ist ein Programm, das Informationen aus dem Web sammelt. Lassen Sie uns ein Programm entwerfen, das Informationen aus der National Diet Library Search sammelt, indem wir es als "ndl crawler" bezeichnen. Es kann durch das folgende Verfahren entworfen werden.

  1. Verwenden Sie die National Diet Library Search in Ihrem Browser
  2. Geben Sie alle Elemente der erweiterten Suche in alphanumerischen Zeichen ein und führen Sie die Suche aus.
  3. Überprüfen Sie, welches Element welchem Parameter entspricht, indem Sie es mit dem Parameter get vergleichen
  4. Entwerfen Sie das Programm anhand der bis zu 3 erhaltenen Hinweise.

1-1-1. Schritte 1-3

Als ich unter den in Abbildung 1.1.1.1 gezeigten Bedingungen suchte, war die URL der Suchergebnisse (Halsanzeige) wie folgt. https://iss.ndl.go.jp/books?datefrom=1234&place=place&rft.isbn=isbn&rft.title=title&dateto=5678&rft.au=author&subject=subject&do_remote_search=true&rft.pub=publisher&display=thumbnail&ndc=genre&search_mode=advanced

image.png Abbildung 1.1.1.1 URL Suchkriterien für die Parameterbeobachtung

Ein Vergleich zeigt, dass Tabelle 1.1.1.1 zeigt. (In einem anderen Versuch wurde jedoch nur die "Ergebnisseitennummer" bestätigt.)

Tabelle 1.1.1.1 URL-Parameter für die Suche in der Parlamentarischen Nationalbibliothek

Artikel Parameter Wert
Titel rft.title
Autoreneditor rft.au
der Herausgeber rft.pub
Startpunkt des Abschnitts des Veröffentlichungsjahres datefrom
Endpunkt des Abschnitts des Veröffentlichungsjahres dateto
Gegenstand subject
Klassifizierungssymbol ndc
ISBN/ISSN rft.isbn
Ort der Veröffentlichung place
Ergebnisseitennummer page
Ergebnisse als Miniaturansichten anzeigen display thumbnail
Davon abgesehen 1/2 do_remote_search true
Davon abgesehen werde ich es vorerst behalten 2/2 search_mode advance

1-1-2. Schritt 4 (Crawler-Design)

Erstellen Sie das Java-Paket "ndl" und erstellen Sie die folgende "NDL Rawler.java" darin. (Die im Code angezeigte Parser-Klasse wird in Abschnitt 1-1-3 beschrieben. Kurz gesagt, der Inhalt der Ergebnisseite, die an den Konstruktor übergeben wird, wird mit der Methode parse () in csv umgewandelt. Die Methode has15 () gibt einen booleschen Wert zurück, der angibt, ob das Ergebnis 15 ist. ) (Die WebGetter-Klasse, die im Code angezeigt wird, dient nur dazu, die HTML-Quelle mit der Methode "get" aus dem Internet abzurufen.)

NDLCrawler.java


package ndl;

import java.io.*;
import java.net.*;

public class NDLCrawler
{
	private String url = "https://iss.ndl.go.jp/books?",
	title="", author="", publisher="", yearfrom="",yearto="", subject="", bunrui="", isbn_issn="", place="";
	public void setTitle(String str){title=str;} public void setAuthor(String str){author=str;} public void setPublisher(String str){publisher=str;} public void setYearfrom(String str){yearfrom=str;} public void setYearto(String str){yearto=str;} public void setSubject(String str){subject=str;} public void setBunrui(String str){bunrui=str;} public void setIsbn_issn(String str){isbn_issn=str;} public void setPlace(String str){place=str;}
	public String crawle()
	{
		System.out.println("Crawler starten");
		String csv="";
		String urlWithGet = url+ "rft.title=" + title + "&rft.au=" + author + "&rft.pub=" + publisher + "&datefrom=" + yearfrom + "&dateto=" + yearto + "&subject=" + subject + "&ndc=" + bunrui + "&rft.isbn=" + isbn_issn + "&place=" + place;
		urlWithGet = urlWithGet + "&do_remote_search=true&display=thumbnail&search_mode=advanced";
		System.out.println("  url:"+urlWithGet+"&page=(Seitennummer)");
		WebGetter wg = new WebGetter();
							try {
		for(int page=1; page<=34; page++)
		{
			System.out.println("   "+page+"Seite Seite");
			String source = wg.get(urlWithGet+"&page="+page);
			Parser p = new Parser(source, false);
			csv = csv + p.parse().replaceFirst("^(\r\n|\r|\n)", "");
			if(!p.has15()) break;
		}
		System.out.println("Crawler-Ende");
		return csv;
							} catch (IOException e) {e.printStackTrace();return null;}

	}
}

Die WebGetter-Klasse sieht folgendermaßen aus: (Nach NDLCrawler.java hinzufügen)

WebGetter-Klasse


/**
 *
 *Referenzseite:https://www.javalife.jp/2018/04/25/java-%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%AE%E3%82%B5%E3%82%A4%E3%83%88%E3%81%8B%E3%82%89html%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B/
 *
 */
class WebGetter
{
	String get(String url) throws MalformedURLException, IOException
	{
		InputStream is = null; InputStreamReader isr = null; BufferedReader br = null;
							try {
		URLConnection conn = new URL(url).openConnection();
		is = conn.getInputStream();
		isr = new InputStreamReader(is);
		br = new BufferedReader(isr);

		String line, source="";
		while((line = br.readLine()) != null)
			source=source+line+"\r\n";
    	return source;
							}finally {br.close();isr.close();is.close();}
	}

}

1-1-3. Schritt 4 (Erstellen Sie CSV aus der Quelle (HTML) der Ergebnisseite)

Wir haben die folgenden Regeln bezüglich der HTML-Quelle der Suchergebnisse in der "National Diet Library Search" gefunden.

--<a href="https://iss.ndl.go.jp/books/ (Buch-ID, bestehend aus alphanumerischen Zeichen und Bindestrichen) ">(Zeichenfolge 1) steht immer unmittelbar nach dem Buchtitel .. Das Gegenteil gilt mindestens einmal für jedes Buch.

Das folgende Java-Programm erstellt eine CSV-Datei mit Buchtiteln, die gemäß dieser Regel (und einigen Ausnahmen) angeordnet sind. (Der Prozess der Konvertierung der HTML-Quelle in CSV wird als Parse bezeichnet.)

Parser.java


package ndl;

public class Parser
{
	private boolean has15;
	private String csv;

	Parser(String source, boolean needHeader)
	{
		this.csv=needHeader?"National Diet Library Link,Titel,Autor,Herausgeber,Jahr,Serie\n":"\n";
		String[] books = divide(source);//「<a href="https://iss.ndl.go.jp/books/Getrennt durch
		books = remove0(books);//Nur der Anfang ist bedeutungslos Daten, also schneiden Sie es ab
		has15 = books.length==15;//Standardmäßig beträgt die Anzahl der Suchergebnisse 15 pro Seite.
		String link, title, publisher, year, series;
		String[] authors;
		for(String book : books)//Über jedes Buch
		{
			book = book.replaceAll("((\r\n)|\r|\n)( |\t)*<span style=\"font-weight:normal;\">[^<]+</span>","");//Wenn die Serie nummeriert ist, können Sie sie auf das "Gesetz" anwenden, indem Sie diese Informationen ausschneiden.
			link = getLink(book).replaceAll(",", "、");
			title = getTitle(book).replaceAll(",", "、");
			authors = getAuthors(book);
			publisher = getPublisher(book).replaceAll(",", "、");
			year = getYear(book).replaceAll(",", "、");
			series = getSeries(book).replaceAll(",", "、");//Extrahieren Sie detaillierte Informationen
			for(String author : authors)//In CSV konvertieren
				csv = csv + link+","+title+","+author.replaceAll(",", "、")+","+publisher+","+year+","+series+"\n";
		}
	}

	public boolean has15(){return has15;}
	public String parse() {return csv;}

	//Private Methoden, die nicht wirklich gut sind
	private String[] divide(String source){return source.split("<a href=\"https://iss\\.ndl\\.go\\.jp/books/", -1);}
	private String[] remove0(String[] before)
	{
		String[] after = new String[before.length-1];
		for(int i=1; i<before.length; i++)after[i-1]=before[i];
		return after;
	}
	private String getLink(String book){return "https://iss.ndl.go.jp/books/"+book.split("\"")[0];}//「"Sie müssen nur die 0. getrennt durch zurückgeben
	private String getTitle(String book){return book.split("<|>")[1];}//「<Oder ">Sie müssen nur den ersten zurückgeben, der durch getrennt ist
	private String[] getAuthors(String book){return book.split("(\r\n)|\r|\n")[3].replaceFirst("( |\t)*", "").split("/([^,])+,?");}
	private String getPublisher(String book){return book.split("(\r\n)|\r|\n")[5].replaceFirst("( |\t)*", "");}
	private String getYear(String book){return book.split("(\r\n)|\r|\n")[6].replaceFirst("( |\t)*", "");}
	private String getSeries(String book){return book.split("(\r\n)|\r|\n")[7].replaceFirst("( |\t)*", "");}


}

1-1-4. Schritt 4 (Crawler-Steuerung)

Entwarf eine Crawler-Klasse für den Zugriff auf die Suche in der National Diet Library in den Abschnitten 1-1-2 In Abschnitt 1-1-3 haben wir eine Klasse implementiert, die csv basierend auf den vom Crawler erhaltenen Informationen generiert. Entwerfen wir in den Abschnitten 1-1-4 eine Klasse, die den Crawler mithilfe dieser Klassen tatsächlich steuert.

Geben Sie als Steuerungsinhalt jeweils 1925 bis 2020 in der for-Anweisung an, geben Sie 699 als Klassifizierungsnummer an, bedienen Sie den Crawler und schreiben Sie die fertige CSV in die Datei. Wenn Sie die Anzahl der Jahre nicht kennen, wird diese anscheinend als "1900" behandelt. Berücksichtigen Sie dies ebenfalls.

Main.java


package ndl;

import java.io.*;

public class Main
{
	public static void main(String...args)
	{
		String header = "National Diet Library Link,Titel,Autor,Herausgeber,Jahr,Serie,Bibliothek\n";
		NDLCrawler c = new NDLCrawler();
		c.setBunrui("699");
		generateCsv(c);
	}

	private static void generateCsv(NDLCrawler c)
	{
		System.out.println(1900);
		c.setYearfrom("1900");
		c.setYearto("1900");
		output(c.crawle());//Schreiben Sie am Ende
		for(int year=1925; year<=2020; year++)
		{
			System.out.println(" "+year);
			c.setYearfrom(""+year);
			c.setYearto(""+year);
			output(c.crawle());//Schreiben Sie am Ende
		}
	}

	private static void output(String csv)
	{
		String path = "D:\\all699.csv";//Der Pfad kann beliebig geändert werden
		System.out.println("Ausgabe"+csv);
							try{
		FileWriter fw = new FileWriter(path, true);//Additionsmodus am Ende mit dem zweiten Argument true
		fw.write(csv);
		fw.close();
							} catch (IOException e) {e.printStackTrace();}
	}
}

2. Ergebnis

Die Versuchsumgebung und -bedingungen sind in Tabelle 2-1 gezeigt.

Tabelle 2-1. Versuchsumgebung und -bedingungen

Item Value
OS windows10
Software Eclipse IDE für Enterprise Java-Entwickler (4.11.0)
Anbieter und Quellen Jupiter Telecommunication Co. Ltd (210.194.32.203)
Datum und Uhrzeit des Programmstarts (japanische Zeit) 17. Januar 2020 20:44:00
Programmstoppzeit und Betriebsdauer, Grund für den Stopp 17. Januar 2020 21:39:44
(ca. 56 Minuten, normales Ende)

Die Ausgabedatei all699.csv (hochgeladen auf github) erreichte 12145 Zeilen.

Außerdem habe ich nach dem Experiment mit einem Browser auf die Suche in der National Diet Library zugegriffen und mir die Nummerninformationen in den Suchergebnissen unter den gleichen Bedingungen angesehen, nämlich 12633. Aufgrund der Inkonsistenz in der Anzahl der Bücher haben wir untersucht und festgestellt, dass die Gesamtzahl der Bücher, die 1900 und 1925-2020 als Informationen zum Veröffentlichungsjahr angegeben wurden, 12030 beträgt. Dies ist etwas weniger als 12145, aber es wird angenommen, dass dies auf die Spezifikation der Methode "Parser.getAuthors" zurückzuführen ist, die besagt, dass "bei mehreren Autoreninformationen jede Zeile separat zugewiesen wird".

3. Zukunftsaussichten

In der Nationalbibliothekensuche der Nationalversammlung können Sie zusätzlich zur Nationalbibliothek der Nationalversammlung die Sammlungen mehrerer lokaler Bibliotheken durchsuchen. Ich bin daran interessiert, dies zu verwenden, um es auf Forschung anzuwenden, die "Bücher, die überall platziert sind" und "Bücher, die nicht platziert sind" klassifiziert. Deshalb möchte ich dies versuchen.

Recommended Posts

Erstellen Sie eine Datenbank aller Bücher, die im letzten Jahrhundert in Japan im Umlauf waren
Lassen Sie uns eine TODO-App in Java 5 erstellen. Schalten Sie die Anzeige von TODO um
[Android] Entwickeln Sie einen Dienst, mit dem Universitätsstudenten den Betriebsstatus von Bussen überprüfen können, die an der Universität verkehren.
Beispielprogramm, das den Hashwert einer Datei in Java zurückgibt
Erstellen eines Beispielprogramms mit dem Problem eines Datenbankspezialisten für DDD-Verbesserung 2
Ich kann das Paket nicht importieren, das auf Anaconda installiert sein sollte
Erstellen eines Beispielprogramms mit dem Problem eines Datenbankspezialisten mit DDD-Verbesserung 1
Code zum Löschen aller Dateien mit dem angegebenen Präfix in AWS S3 (Java)
Messen Sie die Größe eines Ordners mit Java
Löschen Sie alle Datensätze in einer Tabelle in einer MySQL-Datenbank