我正在尝试创建一个站点地图生成器。简而言之,我为它提供了一个链接,它在网站上寻找更多链接,依此类推。
为了避免长链缠结,我认为我可以创建一个blocked_sites.txt
,我可以从中读取unprocessed_urls
并与之比较,并删除所有包含的项目阻止者。
我的问题是,天真的我认为我可以简单地进行一些设置/列表比较和删除,然后完成中提琴操作,但问题主要是collection *deque*
< / p>
代码
我首先定义了我的string url,这是用户输入,然后将其添加到que:
# a queue of urls to be crawled
unprocessed_urls = deque([starting_url])
现在是我开始处理网址的部分:
# process urls one by one from unprocessed_url queue until queue is empty
while len(unprocessed_urls):
# Remove unwanted items
unprocessed_urls = {url for url in unprocessed_urls if not any(blocker in url for blocker in blockers)} <-- THIS IS THE PROBLEM
# move next url from the queue to the set of processed urls
newurl = unprocessed_urls.popleft()
processed_urls.add(newurl)
# extract base url to resolve relative links
parts = urlsplit(newurl)
base_url = "{0.scheme}://{0.netloc}".format(parts)
if parts.scheme !='mailto' and parts.scheme !='#':
path = newurl[:newurl.rfind('/')+1] if '/' in parts.path else newurl
else:
continue
# get url's content
print(Fore.CYAN + "Crawling URL %s" % newurl + Fore.WHITE)
try:
response = requests.get(newurl, timeout=3)
所以问题是,该程序不应进入大型网站,我已明确定义为被阻止,例如:
# Blockers
blockers = set(line.strip() for line in open('blocked_sites.txt'))
然后使用建议的方法从不需要的地方剥离unprocessed_urls
,我使用了以下这一行代码(代码中也指出了这一点):
# Remove unwanted items
unprocessed_urls = {url for url in unprocessed_urls if not any(blocker in url for blocker in blockers)}
因此我们在这里找到自己:
AttributeError: 'set' object has no attribute 'popleft'
我能想到的是,通过尝试删除不需要的项目,它以某种方式改变了collection
我真的不知道如何从这里前进。
答案 0 :(得分:0)
第unprocessed_urls = {...}
行创建一个新的set
对象,并将其分配给unprocessed_urls
。这个新值在逻辑上类似于旧值的事实是无关紧要的;分配给变量会覆盖之前的内容。
但是,可以从任何迭代创建collections.deque
,因此您可以这样做
unprocessed_urls = deque(url for url in unprocessed_urls if ...)
创建一个新的collections.deque
,以便您分配给unprocessed_urls
的所有值都具有相同的类型。