Das Ergebnis der Webseite kann gleich oder verschieden, je nach ‚zusätzlichen Parametern‘ sein. Daher können Sie Regeln, die doppelte Inhalte erkennen, im Allgemeinen nur durch Betrachten der URL nicht definieren.
würde ich vorschlagen, url1 und url2 als different.Compute eine MD5-Summe von jedem Block sagen 1024 Worte aus dem Urls empfangen zu behandeln. Pflegen Sie eine Hash-Map dieser md5sums, um Dubletten erkennen zu können.
Wahrscheinlich einige der Funktionen einige web crawling tools könnten Sie benötigen bieten.
Update basierend auf OP-Kommentare: Ich schrieb einen Code, um meine Antwort zu verbessern. Es gibt zwei Versionen: die erste ist einfacher:
def find_matches():
"""
Basic version: reads urls, but does not consider the semantic information of
HTML header, body, etc. while computing duplicates.
"""
from urllib2 import urlopen
import hashlib
urls = [ 'http://www.google.com', 'http://www.google.com/search']
d = {}
url_contents = {}
matches = []
for url in urls:
c = urlopen(url)
url_contents[url] = []
while 1:
r = c.read(4096)
if not r: break
md5 = hashlib.md5(r).hexdigest()
url_contents[url].append(md5)
if md5 in d:
url2 = d[md5]
matches.append((md5, url, url2))
else:
d[md5] = []
d[md5].append(url)
#print url_contents
print matches
if __name__ == '__main__':
find_matches()
Es war naiv der obige Code zu erwarten Duplikate zu erkennen, in der erwarteten Art und Weise: die aktuellen Web-Seiten sind viel zu komplex. Daher haben sogar zwei URLs, die für die Augen eines Benutzers die gleichen sind, tatsächlich viele Unterschiede aufgrund von Anzeigen, Hash-Tags, Selbst-URL-Namenseinschluss usw.
Die zweite Version ist anspruchsvoller. Es führt eine begrenzte semantische Analyse des Inhalts basierend auf BeautifulSoup:
def find_matches():
"""
Some consideration of the HTML header, body, etc. while computing duplicates.
"""
from urllib2 import urlopen
import hashlib
from BeautifulSoup import BeautifulSoup
import pprint
urls = [ 'http://www.google.com', 'http://www.google.com/search'] # assuming all distinct urls
def txt_md5(txt):
return hashlib.md5(txt).hexdigest()
MAX_FILE_SIZE = 1024*1024*1024
d = {}
url_contents = {}
matches = []
for url in urls:
try:
c = urlopen(url)
url_contents[url] = []
r = c.read(MAX_FILE_SIZE)
soup = BeautifulSoup(r)
header = soup.find('head').text
body = soup.find('body').text
# More fine-grained content options
# like h1, h2, p, etc., can be included.
# Common CSS tags like page, content, etc.
# can also be included.
for h in [header, body]:
print h
md5 = txt_md5(h)
url_contents[url].append((md5, h))
if md5 in d:
url2 = d[md5]
matches.append((md5, url, url2))
else:
d[md5] = []
d[md5].append(url)
except Exception as e:
print "Exception", e
print '---------------'
#pprint.pprint(url_contents)
print matches
if __name__ == '__main__':
find_matches()
Aber auch die zweite Version funktioniert nicht. Der Grund bleibt gleich. Tatsächlich war der Unterschied zwischen den Kopftexten der beiden URLs ein eingeschlossener Hashwert und der Unterschied zwischen den Textstellen der beiden URLs war eine Zeichenkette webhp
. Ich benutzte difflib.context_diff, um den Unterschied zu berechnen.
Es ist möglich, den Code zu verbessern, um eine dritte Version enthält, die die Web-Seiten mehr intelligent analysiert und berechnet die diff intelligent mehr. Zum Beispiel deklarieren Sie als Duplikate sogar die Texte mit < 5% diff (dieses Verhältnis kann leicht mit einer difflib-Funktion berechnet werden).
hallo phaedurs, das ist wunderbar. ich danke Ihnen sehr für Ihre Antwort. Würden Sie mir gerne einige detaillierte Tipps geben, wie Sie "eine Hash-Karte dieser md5sums verwalten, um Dubletten erkennen zu können". Eigentlich habe ich rabiat gelernt, aber es ist ziemlich kompliziert zu meinem aktuellen Projekt. – mrblue