我正在使用python中的一个简单的Web爬虫,我不想创建一个简单的队列类,但我不太确定最好的启动方式。我想要的东西只包含要处理的唯一项目,因此爬虫只会在每个脚本运行时抓取每个页面一次(只是为了避免无限循环)。任何人都可以给我或指向一个我可以逃避的简单队列示例吗?
答案 0 :(得分:4)
我只是使用一套,它不维持秩序,但它会帮助你保持唯一性:
>>> q = set([9, 8, 7, 7, 8, 5, 4, 1])
>>> q.pop()
1
>>> q.pop()
4
>>> q.pop()
5
>>> q.add(3)
>>> q.add(3)
>>> q.add(3)
>>> q.add(3)
>>> q
set([3, 7, 8, 9]
答案 1 :(得分:2)
一个非常简单的例子是将每个项目的URL填充到一个dict中,但作为键,而不是值。然后只处理下一个项目,如果它的url不在该dict的键中:
visited = {}
# grab next url from somewhere
if url not in visited.keys():
# process url
visited[url] = 1 # or whatever, the value is unimportant
# repeat with next url
当然,你可以提高效率,但这很简单。
答案 2 :(得分:2)
如果我理解正确,您只想访问每个页面一次。我认为最好的方法是保持一个页面队列仍然可以访问,以及一组访问过的页面。另一个发布的解决方案的问题是,一旦你从队列中弹出一个页面,你就不再记录你是否去过那里。
我会使用集合和列表的组合:
visited = set()
to_visit = []
def queue_page(url):
if url not in visited:
to_visit.append(url)
def visit(url):
visited.add(url)
... # some processing
# Add all found links to the queue
for link in links:
queue_page(link)
def page_iterator(start_url):
visit(start_url)
try:
yield to_visit.pop(0)
except IndexError:
raise StopIteration
for page in page_iterator(start):
visit(page)
当然这是一个人为的例子,你可能最好以某种方式封装它,但它说明了这个概念。
答案 3 :(得分:1)
为什么不使用列表如果你需要订单(甚至是一个heapq,就像zacherates之前建议的那样在建议集合之前)并且还使用一个集来检查重复项?
答案 4 :(得分:0)
我会扩展list类,将唯一测试代码添加到您正在使用的列表的任何方法中。这可以是简单地将.append_unique(item)
添加到班级,或覆盖所有append
,insert
,extend
,__setitem__
,__setslice__
,等,在非唯一项目的情况下抛出异常(或者如果你愿意,则保持沉默)。
例如,如果您只是想确保append方法保持唯一性:
class UniqueList(list):
def append(self, item):
if item not in self:
list.append(self, item)