2016-05-11 8 views
2

im Moment .txt ich mit diesem Code arbeite:Öffnen jeder Datei/Unterordner im Verzeichnis und Druckergebnisse Datei

from bs4 import BeautifulSoup 
import glob 
import os 
import re 
import contextlib 


@contextlib.contextmanager 
def stdout2file(fname): 
    import sys 
    f = open(fname, 'w') 
    sys.stdout = f 
    yield 
    sys.stdout = sys.__stdout__ 
    f.close() 

def trade_spider(): 
    os.chdir(r"C:\Users\6930p\FLO'S DATEIEN\Master FAU\Sommersemester 2016\02_Masterarbeit\04_Testumgebung\01_Probedateien für Analyseaspekt\Independent Auditors Report") 
    with stdout2file("output.txt"): 
     for file in glob.iglob('**/*.html', recursive=True): 
      with open(file, encoding="utf8") as f: 
       contents = f.read() 
       soup = BeautifulSoup(contents, "html.parser") 
       for item in soup.findAll("ix:nonfraction"): 
        if re.match(".*AuditFeesExpenses", item['name']): 
         print(file.split(os.path.sep)[-1], end="| ") 
         print(item['name'], end="| ") 
         print(item.get_text()) 
trade_spider() 

Bisher dies funktioniert perfekt. Aber jetzt bin ich mit einem anderen Problem beschäftigt. Wenn ich in einem Ordner suche, der keine Unterordner, sondern nur Dateien enthält, funktioniert das ohne Probleme. Wenn ich jedoch versuche, diesen Code in einem Ordner mit Unterordnern auszuführen, funktioniert er nicht (er gibt nichts aus!). Außerdem möchte ich meine Ergebnisse in eine TXT-Datei drucken lassen, ohne den gesamten Pfad darin zu haben. Das Ergebnis sollte wie:

Filename.html| RegEX Match| HTML text 

ich schon dieses Ergebnis zu tun bekommen, aber nur in PyCharm und nicht in einer separaten .txt-Datei.

zu summieren, habe ich 2 Fragen:

  1. Wie kann ich meine definierten Verzeichnis zu Fuß durch Unterordner auch? -> würde os.walk() eine Option dafür sein?
  2. Wie kann ich meine Ergebnisse in eine TXT-Datei drucken? -> Würde sys.stdout daran arbeiten?

Jede Hilfe zu diesem Thema geschätzt!

UPDATE: Es druckt nur die ersten Ergebnisse der ersten Datei in meine "outout.txt" -Datei (zumindest denke ich, es ist die erste, da es die letzte Datei in meinem einzigen Unterordner ist und recursive = true aktiviert ist). Irgendeine Idee, warum es nicht alle anderen Dateien durchläuft?

UPDATE_2: Frage gelöst! Der endgültige Code kann oben gesehen werden!

Antwort

1

Für in Unterverzeichnisse gehen, gibt es zwei Möglichkeiten:

  1. Verwenden ** mit glob und das Argument recursive=True (glob.glob('**/*.html')). Dies funktioniert nur in Python 3.5+. Ich würde auch empfehlen, glob.iglob anstelle von glob.glob zu verwenden, wenn der Verzeichnisbaum groß ist.

  2. Verwenden Sie os.walk und überprüfen Sie die Dateinamen (ob sie in ".html" enden) manuell oder mit fnmatch.filter.


In Bezug auf den Druck in eine Datei, gibt es wieder mehrere Möglichkeiten:

  1. einfach das Skript ausführen und stdout umleiten, dh python3 myscript.py >myfile.txt

  2. Anrufe ersetzen zu print mit Ein Aufruf der Methode .write() eines Dateiobjekts im Schreibmodus.

  3. Verwenden Sie weiterhin drucken, aber geben Sie das Argument file=myfile wo myfile wieder ein beschreibbares Dateiobjekt ist.

edit: Vielleicht die unaufdringliche Methode wäre die folgende sein. Erstens, um diesen irgendwo:

import contextlib 
@contextlib.contextmanager 
def stdout2file(fname): 
    import sys 
    f = open(fname, 'w') 
    sys.stdout = f 
    yield 
    sys.stdout = sys.__stdout__ 
    f.close() 

Und dann, infront der Linie, in der Sie Schleife über die Dateien, diese Zeile hinzufügen (und entsprechend Gedankenstrich):

with stdout2file("output.txt"): 
+0

In Ordnung. Der erste Teil mit glob.iglob funktioniert (fast) perfekt. Es findet jetzt alle Dateien, aber es druckt auch den Ordnernamen vor meiner gewünschten Ausgabe. Jede Möglichkeit, in allen Unterordnern zu suchen, aber NUR den Dateinamen.html zu drucken, wie ich in meiner Frage schrieb? –

+1

Sie benötigen den vollständigen Pfad zum Öffnen der Dateien, aber wenn Sie nur den Dateinamen selbst im Aufruf von 'print' anzeigen möchten, können Sie' print (file.split (os.path.sep) [- 1] , Ende = "|") '. – L3viathan

+0

Welche Option wäre die eleganteste Lösung ohne meinen Code zu ändern, um meine Ergebnisse in eine Textdatei zu bringen? Ich dachte zuerst, das sollte kein großes Problem sein ... –