Ich habe den Text der in Aozora Bunko veröffentlichten Arbeit mit Python abgekratzt und zu einem schönen Gefühl verarbeitet. Zu dieser Zeit war ich hier und da süchtig danach, also dieses Memorandum.
Holen Sie sich zuerst den Text der Arbeit von Aozora Bunko.
Was zu tun ist, ist im Wesentlichen wie in diesem Artikel beschrieben (https://qiita.com/icy_mountain/items/011c9f56151b9832b54d), [Aozora Bunko API (https://qiita.com/ksato9700/items/626cc82c007ba8337034) Drücken Sie, um den HTML-Code des Körpers abzurufen. Zu diesem Zeitpunkt wird der Arbeits-ID-Teil der URL auf "book_id" und eine Variable gesetzt.
In meiner eigenen Umgebung konnte ich dies jedoch nicht tun. Zuerst habe ich am Jupyter-Notizbuch anstatt am Terminal gearbeitet, daher kann ich den Befehl ! Wget
nicht verwenden.
Wenn Sie also den Befehl nachschlagen, der eine GET-Anforderung an die API in Python sendet, werden zwei angezeigt: "urllib2.urlopen ()" und "reqests.req ()". Von diesen ist "urllib2" eine Bibliothek für Python2. Kann ich nicht benutzen. Es scheint, dass es in Python3 in "urllib3" oder "urllib" umbenannt wurde, aber ich war mir nicht sicher, also habe ich beschlossen, die "Anfragen" -Bibliothek zu verwenden. Der API-Abruf mit der GET-Methode sieht also folgendermaßen aus:
import requests
res = requests.get('http://pubserver2.herokuapp.com/api/v0.1/books/{book_id}/content?format=html'.format(book_id))
Konvertieren Sie anschließend die abgerufenen HTML-Daten in ein Format, das von BeautifulSoup4 verwendet werden kann.
from bs4 import BeautifulSoup
soup = BeautifulSoup(res.text, 'html.parser')
Um den Text des title
-Tags von hier zu erhalten, schreiben Sie:
soup.find('title').get_text()
# ->Hisaku Yumeno Ao Suisen, Roter Suisen
Die Titel sind durch Leerzeichen mit halber Breite gut voneinander getrennt. Wenn Sie hier also "split ()" ausführen, können Sie sie in den Namen und den Titel des Autors unterteilen. In einigen Fällen, z. B. bei ausländischen Autoren, läuft es möglicherweise nicht gut, sodass das Vorhandensein oder Fehlen der verbleibenden Informationen auch in der Variablen festgelegt wird.
title_list = title.split(' ')
book_author = title_list[0] #Autorenname
book_title = title_list[1] #Titel
book_title_info = len(title_list) > 2 #Ist der Titel gebrochen?
Auf der anderen Seite ist der Körper (im wahrsten Sinne des Wortes) das "div" -Tag der "main_text" -Klasse, also würde es so aussehen:
soup.find('div', {'class': 'main_text'}).get_text()
# -> \n\n\n\r\n\u3000 Utako wurde von einem Freund gelehrt, die Wurzeln von Narzissen zu schneiden, rote und blaue Farben in sie zu geben und sie in der Ecke des Gartens zu begraben.[...]
Dieses Mal möchte ich Sätze durch Interpunktion trennen, daher erstelle ich für jeden Satz ein Listenformat wie folgt. Wenn Sie den ersten Satz möchten, können Sie ihn als 0. Element erhalten.
text_list = soup.find('div', {'class': 'main_text'}).get_text().split('。')
text_first = text_list[0] + "。" #Der erste Satz
Wenn dies so bleibt, wird der Text verschmutzt, sodass unnötige Elemente entfernt und der Text verfeinert werden. Da der Code, der dem Zeilenvorschubcode "\ n" und dem Raum halber Breite "\ u3000" entspricht, gemischt ist, lassen Sie ihn zunächst mit "strip ()" nach "get_text ()" fallen.
text_list = soup.find('div', {'class': 'main_text'}).get_text().strip('\r''\n''\u3000').split('。')
Um den in Text in Klammern eingeschlossenen Teil des Rubins zu entfernen, fügen Sie unmittelbar nach der Konvertierung den folgenden Code hinzu, um den Rubin zu entfernen.
for tag in soup.find_all(["rt", "rp"]):
tag.decompose() #Tags und deren Inhalt löschen
Manchmal wird es nicht durch Interpunktion getrennt, und der erste Satz kann endlos fortgesetzt werden. Wenn er also zu lang ist, werde ich ihn durch eine andere Zeichenfolge ersetzen. Der Längenstandard 100 ist angemessen.
text_first = text_list[0] + "。" if (len(text_list[0]) < 100) else "too long" #Anfang
Wenn beim Konvertieren des obigen Prozesses in eine Funktion die entsprechende Arbeits-ID nicht vorhanden ist und das Abrufen fehlschlägt, tritt zum Zeitpunkt der Extraktion ein NoneType-Fehler auf. Schließen Sie dies daher durch das Vorhandensein oder Fehlen von Tags und Klassen aus. (Ich denke, es gibt einen besseren Weg, es zu schreiben).
if (soup.find('title') is None) or (soup.find('div') is None) or (soup.find('div', {'class': 'main_text'}) is None):
return [book_id, '', '', '', '', '' ]
else:
title = soup.find('title').get_text()
[...]
bookInfo.py
def bookInfo(book_id):
import requests
from bs4 import BeautifulSoup
res = requests.get(f'http://pubserver2.herokuapp.com/api/v0.1/books/{book_id}/content?format=html')
soup = BeautifulSoup(res.text, 'html.parser')
for tag in soup.find_all(["rt", "rp"]):
tag.decompose() #Tags und deren Inhalt löschen
if (soup.find('title') is None) or (soup.find('div') is None) or (soup.find('div', {'class': 'main_text'}) is None):
return [book_id, '', '', '', '']
else:
title = soup.find('title').get_text()
title_list = title.split(' ')
book_author = title_list[0] #Autorenname
book_title = title_list[1] #Titel
book_title_info = len(title_list) > 2 #Ist der Titel gebrochen?
print(soup.find('div', {'class': 'main_text'}))
text_list = soup.find('div', {'class': 'main_text'}).get_text().strip('\r''\n''\u3000').split('。')
text_first = text_list[0] + "。" if (len(text_list[0]) < 100) else "too long" #Anfang
else:
text_last = ""
list = [book_id, book_author, book_title, book_title_info, text_first]
print(list)
return list
bookInfo(930)
# -> [930,
# 'Hisaku Yumeno',
# 'Das Wunder von Oshie',
# False,
# 'Wenn ich die Schlaflücke der Krankenschwester sehe, habe ich eine arme weibliche Figur, daher denke ich, dass es schwierig ist zu lesen und zu verstehen, aber ich werde Ihnen viele Male vergeben, wenn ich mich beeile. Bitte.']
Ich möchte die mit der obigen Funktion erhaltenen Listen hinzufügen, um eine zweidimensionale Liste zu erstellen und sie als CSV-Datei auszugeben.
Importieren Sie zuerst csv
und öffnen Sie die Datei.
Übrigens, wenn die Datei bereits vorhanden ist und Sie sie nach dem vollständigen Text hinzufügen möchten, anstatt sie zu überschreiben, ändern Sie "w" in "a".
import csv
f = open('output.csv', 'w')
writer = csv.writer(f, lineterminator='\n')
Erstellen Sie eine leere Liste und drehen Sie die for-Schleife, um den Rückgabewert der Ausführung der Funktion zur Liste hinzuzufügen. Mit der Aozora Bunko-API dauerte es übrigens einige Sekunden, bis eine Arbeit fertig war. Ich bin der Meinung, dass wenn Sie zu viele Anfragen anfordern, diese unbrauchbar werden. Ich denke, es ist besser, sie in kleinen Einheiten wie 10 oder 100 auszuführen.
csvlist = []
for i in range(930, 940):
csvlist.append(bookInfo(i))
Schließen Sie schließlich die Datei und Sie sind fertig.
writer.writerows(csvlist)
f.close()
Eine CSV-Datei wurde ausgegeben. Es ist bequem, es in eine Google-Tabelle zu laden.
930,Hisaku Yumeno,Das Wunder von Oshie,False,Wenn ich die Schlaflücke der Krankenschwester sehe, habe ich eine arme weibliche Figur, daher denke ich, dass es schwierig ist zu lesen und zu verstehen, aber ich werde Ihnen viele Male vergeben, wenn ich mich beeile. Bitte.
Recommended Posts