正则表达式:匹配重复的未知组?

时间:2015-09-28 11:15:39

标签: regex web-crawler

我试图为抓取工具创建一个通用的正则表达式模式,以避免所谓的"抓取器陷阱" (链接只是添加url参数并引用完全相同的页面,这会导致大量无用的数据)。很多时候,这些链接只是一遍又一遍地将相同的部分添加到URL中。以下是日志文件中的示例:

http://examplepage.com/cssms/chrome/cssms/chrome/cssms/pages/browse/cssms/pages/misc/...

我可以使用正则表达式来缩小爬虫的范围,我希望有一个模式,告诉爬虫忽略所有具有重复部分的东西。这有可能与正则表达式? 提前感谢您的一些提示!

只是要澄清:

crawlertraps并非旨在防止爬行,它们是网页设计不佳的结果。我们正在抓取的所有页面都允许我们这样做!

2 个答案:

答案 0 :(得分:2)

如果您已经遍历URL列表,则可以添加匹配作为跳过当前迭代的条件:

array = ["/abcd/abcd/abcd/abcd/", "http://examplepage.com/cssms/chrome/cssms/chrome/cssms/pages/browse/cssms/pages/misc/", "http://examplepage/apple/cake/banana/"]

import re
pattern1 = re.compile(r'.*?([^\/\&?]{4,})(?:[\/\&\?])(.*?\1){3,}.*')

for url in array:
    if re.match(pattern1, url):
        print "It matches; skipping this URL"
        continue 
    print url 

示例正则表达式:

.*?([^\/\&?]{4,})(?:[\/\&\?])(.*?\1){3,}.*

([^\/\&?]{4,})匹配并捕获任何内容的序列,但不包含[/&;],重复4次或更多次。 (?:[\/\&\?])寻找一个/,&要么 ? (.*?(?:[\/\&\?])\1){3,}匹配任何内容,直到[/&?],然后是我们捕获的内容,执行所有这3次或更多次。 demo

答案 1 :(得分:1)

您可以在Python / PERL正则表达式(以及可能的其他正则表达式)中使用反向引用来捕获重复的模式:

>>> re.search(r"(/.+)\1", "http://examplepage.com/cssms/chrome/cssms/chrome/cssms/pages/browse/cssms/pages/misc/").group(1)
'/cssms/chrome'

\1引用第一个匹配,因此(/.+)\1表示连续两次重复的相同序列。前导/只是为了避免正则表达式匹配第一个单个重复字母(t中的http)并捕获路径中的重复。