问题
Downloading this page and making a minor edit to it, changing the first 65 in this paragraph to 68:
I then parse both sources with BeauifulSoup and diff them with difflib.
url = 'https://secure.ssa.gov/apps10/reference.nsf/links/02092016062645AM'
response = urllib2.urlopen(url)
content = response.read() # get response as list of lines
url2 = 'file:///Users/Pyderman/projects/temp/02092016062645AM-modified.html'
response2 = urllib2.urlopen(url2)
content2 = response2.read() # get response as list of lines
import difflib
d = difflib.Differ()
diffed = d.compare(content, content)
soup = bs4.BeautifulSoup(content, "lxml")
soup2= bs4.BeautifulSoup(content2, "lxml")
diff = d.compare(list(soup.stripped_strings), list(soup2.stripped_strings))
changes = [change for change in diff if change.startswith('-') or change.startswith('+')]
for change in changes:
print change
Printing the changes gives:
- The Achieving a Better Life Experience (ABLE) Act, H.R. 5771, legislation passed on December 19, 2014. It contains a Title II provision that changes the age at which workers compensation/public disability offset ends for disability beneficiaries from age 65 to full retirement age (FRA). This provision will apply to any individual who attains age 65 on or after December 19, 2015 (the one year anniversary of enactment of this bill). Two new Universal Text Identifiers (UTIs), UTI WCP060 and WCP061 were created to comply with this change.
+ The Achieving a Better Life Experience (ABLE) Act, H.R. 5771, legislation passed on December 19, 2014. It contains a Title II provision that changes the age at which workers compensation/public disability offset ends for disability beneficiaries from age 68 to full retirement age (FRA). This provision will apply to any individual who attains age 65 on or after December 19, 2015 (the one year anniversary of enactment of this bill). Two new Universal Text Identifiers (UTIs), UTI WCP060 and WCP061 were created to comply with this change.
So it's printing the whole paragraph, despite the very minor change. I suppose it's a good thing that it's showing the diff by the full paragraph rather than by sentence, but can we make the output more granular somehow? As it stands, it seems if I want to highlight just the text that changed, I'll have to do some additional delta comparison of these two almost-identical strings.
回答1:
You can use nltk.sent_tokenize() to split soup strings into sentences:
from nltk import sent_tokenize
sentences = [sentence for string in soup.stripped_strings for sentence in sent_tokenize(string)]
sentences2 = [sentence for string in soup2.stripped_strings for sentence in sent_tokenize(string)]
diff = d.compare(sentences, sentences2)
changes = [change for change in diff if change.startswith('-') or change.startswith('+')]
for change in changes:
print(change)
Prints only an appropriate sentence where the change was detected:
- It contains a Title II provision that changes the age at which workers compensation/public disability offset ends for disability beneficiaries from age 65 to full retirement age (FRA).
+ It contains a Title II provision that changes the age at which workers compensation/public disability offset ends for disability beneficiaries from age 68 to full retirement age (FRA).
来源:https://stackoverflow.com/questions/35375004/getting-more-granular-diffs-from-difflib-or-a-way-to-post-process-a-diff-to-ach