比较两个文本文件并仅将差异附加到一个文件

时间:2016-12-15 08:55:46

标签: python web-scraping

我正在macOS下编写一个程序,它登录到网站的聊天室,抓取内容,将其写入文件并格式化。它运行良好(尽管速度很慢),但它只会刮掉聊天室对运行时的看法。我想做的是附加差异。

我想到这样做的一种方式(因此标题)是拥有一个主文件和一个临时文件。主文件始终存在,临时文件只是写入然后与主文件进行比较。比较这两个文件,两者之间存在的差异从temp复制到master。我对其他解决方案持开放态度,但这似乎是可行的。这些文件将始终在本地生效,程序也将在本地运行。

我不知道从哪里开始。我的代码如下。我知道它很乱,需要修改;我仍然是Python的初学者。

import mechanize
import fileinput
import re
from os import chdir
from os import environ
from time import strftime

home = environ['HOME']
file = "ChatLog_" + strftime("%F") + ".txt"
filename = home + "/" + file
chdir(home + '/Desktop/')

# get login forms
def select_form(form):
    return form.attrs.get('id', None) == 'auth' 

#  authenticate and log raw chat    
def auth():
        br = mechanize.Browser()
        br.set_handle_robots(False)
        br.open('http://website.com/endpoint')
        br.select_form(predicate=select_form)
        br.form['name'] = "username"
        br.form['pass'] = "password"
        br.submit()
        text_file = open(filename, 'w')
        response = br.response().read()
        text_file.write(response)
        text_file.close()

n = 0
while n < 9999:
    try:
        auth()

        # strip first line
        with open(filename, 'r') as fin:
            data = fin.read().splitlines(True)
        with open(filename, 'w') as fout:
            fout.writelines(data[2:])

        # strip nbsp characters 
        with open(filename, 'r+') as f:
            text = f.read()
            text = re.sub('&nbsp;', '', text)
            f.seek(0)
            f.write(text)
            f.truncate()

        # strip #039 apostrophe characters
        with open(filename, 'r+') as f:
            text = f.read()
            text = re.sub('&#039;', '\'', text)
            f.seek(0)
            f.write(text)
            f.truncate()

        # strip everything that lives in and around brackets, i.e. HTML tags
        with open(filename, 'r+') as f:
            text = f.read()
            text = re.sub('<.*?>', '', text)
            f.seek(0)
            f.write(text)
            f.truncate()

        n = n + 1
        print(n)
    except KeyboardInterrupt: print("\nUser aborted."); quit()

1 个答案:

答案 0 :(得分:2)

如果你想连续ping网站并且不介意跳过重复的行(你能安全地假设用户通常不会写同样的东西吗?)你可以通过一种快速的方式来存储结果你的集合。然后,通过他们的symmetric differencedifference,您可以看到他们的不同之处。您使用的版本取决于您要应用的逻辑:

  

<强>差异(*其他)
  set - other - ...
  返回一个新集合,其中集合中的元素不在其他元素中。

     

<强> symmetric_difference(其他)
  set ^ other
  返回一个新集合,其中包含集合或其他中的元素,但不能同时返回两者。

示例:

 old_lines=['chat1', 'chat2']
 new_lines = ['chat1', 'chat2', 'chat3']
 set(old_lines) ^ set(new_lines)

输出{'chat3'}。如果您还关心差异的顺序,只需将set替换为OrderedSet

即可

如果你决定使用diffing文件,那么python标准库就有了difflib。来自docs

>>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n']
>>> s2 = ['python\n', 'eggy\n', 'hamster\n', 'guido\n']
>>> for line in unified_diff(s1, s2, fromfile='before.py', tofile='after.py'):
...     sys.stdout.write(line)   
--- before.py
+++ after.py
@@ -1,4 +1,4 @@
-bacon
-eggs
-ham
+python
+eggy
+hamster
 guido