2017-10-05 6 views
0

Ich versuche, eine Host-Datei mit einem Python-Skript zu verwalten. Ich bin neu bei Python und es fällt mir schwer herauszufinden, wie man eine Zeile ersetzt, wenn ich eine Übereinstimmung finde. Wenn zum Beispiel die Adresse in einer Hostdatei für eine Website geändert wird, möchte ich, dass das Skript sie findet und zurück ändert. Danke für Ihre Hilfe.Python ersetzen Linie in Textdatei

import os 
import time 

#location to the host file to read and write to 
hosts_path=r"C:\Windows\System32\drivers\etc\hosts" 
#the address I want for the sites 
redirect="0.0.0.0" 
#the websites that I will set the address for 
website_list=["portal.citidirect.com","www.bcinet.nc","secure.banque-tahiti.pf","www.bancatlan.hn","www.bancentro.com.ni","www.davivienda.com.sv","www.davivienda.cr","cmo.cibc.com","www.bi.com.gt","empresas.banistmo.com","online.belizebank.com","online.westernunion.com","archive.clickatell.com"] 

#continuous loop 
while True: 
    with open(hosts_path,'r+') as file: 
     content=file.read() 
#for each of the websites in the list above make sure they are in the host file with the correct address 
     for website in website_list: 
      site=redirect+" "+ website 
#here is where I have an issue, if the website is in the host file but with the wrong address I want to write over the line, instead the program is adding it to the end of the file 
      if website in content: 
       if site in content: 
        pass 
       else: 
        file.write(site) 
      else: 
       file.write("\n"+site) 
    time.sleep(300) 

    os.system('ipconfig /flushdns') 
+1

Es ist viel einfacher, die geänderten Zeilen in eine _new_Datei zu schreiben und die Datei anschließend in den alten Namen umzubenennen, wenn Sie fertig sind. Es ist sehr schwierig, eine vorhandene Datei vor Ort zu aktualisieren. –

+0

Das Problem hier ist, dass Sie die gesamte Datei lesen und dann die Daten scannen. Natürlich kann dieses Problem mit diesem Ansatz gelöst werden, aber ein schnellerer und einfacherer Weg wäre, die Datei Zeile für Zeile zu scannen. –

+0

Danke für die Antworten. John Gordon Ich mag die Idee, eine andere Datei zu verwenden. – jbvo

Antwort

1

Sie müssen die Datei in eine Liste lesen, dann den Index der Liste ändert sich, wenn es sein muss, dann schreibt die Liste wieder in die Datei. Was du tust, war nur an das Ende der Datei zu schreiben. Sie können eine Datei nicht direkt so ändern. Sie müssen die Änderungen in einer Liste aufzeichnen und dann die Liste schreiben. Ich musste viel Code neu schreiben. Hier ist das vollständige Skript. Ich war nicht sicher, was die os.system('ipconfig /flushdns') erreicht hat, also entfernte ich es. Sie können es leicht hinzufügen, wo Sie wollen.

#!/usr/bin/env python3.6 

import time 

hosts_path = r"C:\\Windows\\System32\\drivers\\etc\\hosts" 
redirect = "0.0.0.0" 
website_list = [ 
    "portal.citidirect.com", 
    "www.bcinet.nc", 
    "secure.banque-tahiti.pf", 
    "www.bancatlan.hn", 
    "www.bancentro.com.ni", 
    "www.davivienda.com.sv", 
    "www.davivienda.cr", 
    "cmo.cibc.com", 
    "www.bi.com.gt", 
    "empresas.banistmo.com", 
    "online.belizebank.com", 
    "online.westernunion.com", 
    "archive.clickatell.com"] 


def substring_in_list(the_list, substring): 
    for s in the_list: 
     if substring in s: 
      return True 
    return False 


def write_websites(): 
    with open(hosts_path, 'r') as file: 
     content = file.readlines() 
    for website in website_list: 
     site = "{} {}\n".format(redirect, website) 
     if not substring_in_list(content, website): 
      content.append(site) 
     else: 
      for line in content: 
       if site in line: 
        pass 
       elif website in line: 
        line = site 
    with open(hosts_path, "w") as file: 
     file.writelines(content) 


while True: 
    write_websites() 
    time.sleep(300) 
+0

Vielen Dank, dass Sie sich die Zeit genommen haben, zu antworten. Ich mag, wie Sie es in eine separate Funktion getrennt haben. – jbvo

+0

Gern geschehen. Funktionen sind nur gute Praxis. Immer froh zu helfen! – Steampunkery

0

Sie werden also jeder Site die gleiche IP-Adresse zuweisen, die nicht in Ihrer Website-Liste erscheint?

Die folgende ersetzen würde, was in Ihrer äußersten while Schleife ist:

# Read in all the lines from the host file, 
# splitting each into hostname, IPaddr and aliases (if any), 
# and trimming off leading and trailing whitespace from 
# each of these components. 
host_lines = [[component.strip() for component in line.split(None, 2)] for line in open(host_path).readlines()] 

# Process each of the original lines. 
for line in host_lines: 
    # Is the site in our list? 
    if line[1] in website_list: 
     # Make sure the address is correct ... 
     if line[0] != redirect: 
      line[0] == redirect 

     # We can remove this from the websites list. 
     website_list.remove(line[1]) 

# Whatever sites are left in websites don't appear 
# in the hosts file. Add lines for these to host_lines 
host_lines.extend([[redirect, site] for site in website_list]) 

# Write the host_lines back out to the hosts file: 
open(hosts_path, 'w').write("\n".join([" ".join(line) for line in host_lines])) 

Die ganz rechts join Leimen die Komponenten jeder Zeile wieder zusammen in einen einzigen String. Die join auf der linken Seite klebt alle diese Zeichenfolgen zusammen mit Newline-Zeichen zwischen ihnen und schreibt diese gesamte Zeichenfolge in die Datei.

Ich muss sagen, dies sieht wie eine ziemlich komplizierte und sogar gefährliche Art aus, um sicherzustellen, dass Ihre Hosts-Datei aktuell und genau bleibt. Wäre es nicht besser, nur einen cron Job scp eine bekanntermaßen gute Hosts-Datei von einem vertrauenswürdigen Host alle fünf Minuten stattdessen zu haben?

+0

Dies ist für eine temporäre Lösung, um einige Websites auf einigen Computern zu blockieren, während wir daran arbeiten, ein Gerät zu implementieren, das es in Zukunft verarbeiten wird. Ich mag die Idee, eine separate Datei zu verwenden. – jbvo

0

Am Ende mischte ich einige der Antworten, um eine neue Datei zu erstellen, die die aktuelle Host-Datei mit den unten gezeigten Funktionen ersetzt. Zusätzlich zu diesem Code benutze ich pyinstaller, um es in eine exe umzuwandeln, dann habe ich diese exe so eingerichtet, dass sie als Autostart-Dienst ausgeführt wird.

#!/usr/bin/env python3.6 

import os 
import shutil 
import time 

temp_file = r"c:\temp\Web\hosts" 
temp_directory="c:\temp\Web" 
hosts_path = r"C:\Windows\System32\drivers\etc\hosts" 
websites = ('''# Copyright (c) 1993-2009 Microsoft Corp. 
# 
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows. 
# 
# This file contains the mappings of IP addresses to host names. Each 
# entry should be kept on an individual line. The IP address should 
# be placed in the first column followed by the corresponding host name. 
# The IP address and the host name should be separated by at least one 
# space. 
# 
# Additionally, comments (such as these) may be inserted on individual 
# lines or following the machine name denoted by a '#' symbol. 
# 
# For example: 
# 
#  102.54.94.97  rhino.acme.com   # source server 
#  38.25.63.10  x.acme.com    # x client host 

# localhost name resolution is handled within DNS itself. 
# 127.0.0.1  localhost 
# ::1    localhost 
0.0.0.0 portal.citidirect.com 
0.0.0.0 www.bcinet.nc 
0.0.0.0 secure.banque-tahiti.pf 
0.0.0.0 www.bancatlan.hn 
0.0.0.0 www.bancentro.com.ni 
0.0.0.0 www.davivienda.com.sv 
0.0.0.0 www.davivienda.cr 
0.0.0.0 cmo.cibc.com 
0.0.0.0 www.bi.com.gt 
0.0.0.0 empresas.banistmo.com 
0.0.0.0 online.belizebank.com 
0.0.0.0 online.westernunion.com 
0.0.0.0 archive.clickatell.com''') 


def write_websites(): 
    with open(temp_file, 'w+') as file: 
     file.write(websites) 


while True: 
    if not os.path.exists(temp_directory): 
     os.makedirs(temp_directory) 
    try: 
     os.remove(temp_file) 
    except OSError: 
     pass 

    write_websites() 

    try: 
     os.remove(hosts_path) 
    except OSError: 
     pass 

    try: 
     shutil.move(temp_file,hosts_path) 
    except OSError: 
     pass 

    os.system('ipconfig /flushdns') 
    time.sleep(300)