【发布时间】:2018-02-04 01:30:48
【问题描述】:
我有这段代码在Top Alexa 1000 网站上循环,并获得允许Sign Up 或Login 以任何形式出现的代码。如果在此循环的其中一个迭代中有一个网站卡住或以任何形式抛出Exception,我将其从列表中删除,并使用下一个元素重新开始循环。我正在使用Python 中的selenium 包来执行此操作。它工作正常,除了由于某种原因它循环遍历我的 alexa_1000 包含列表的变量中的所有其他元素(即跳过一个元素),而不是遍历每个元素。有人可以帮忙吗?我看到的代码似乎没有什么问题,我一直在调试它以查看程序流程,但真的无法弄清楚发生了什么。该程序的一般流程似乎很好。当我打印每个循环的索引时,要查看跳过的性质,从 0 到 1 到 2 到 3 的意义上来说,这似乎也很好。很高兴有任何帮助。代码如下:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
def get_alexa_top_pages():
sites = []
with open('topsites_1000.txt', 'r') as f:
for line in f:
line = line.strip('\n')
sites.append(line)
sites = filter(None, sites)
sites = ['http://www.' + site for site in sites]
return sites
def main():
alexa_1000 = get_alexa_top_pages()
out = open('sites_with_login.txt', 'w')
sign_in_strings = ['sign in', 'signin', 'login', 'log in', 'sign up', 'signup']
driver = webdriver.Firefox()
driver.set_page_load_timeout(30)
for index, page in enumerate(alexa_1000):
try:
print "Loading page %s (num %d)" %(page, index + 1)
driver.get(page)
html_source = driver.page_source
html_source = html_source.lower()
present = any([i in html_source for i in sign_in_strings])
if present:
out.write(page + '\n')
alexa_1000.remove(page)
except TimeoutException as ex:
alexa_1000.remove(page)
continue
except Exception as ex:
alexa_1000.remove(page)
continue
out.close()
if __name__ == "__main__":
main()
【问题讨论】:
-
在枚举集合时移除元素会干扰枚举。
-
@Jerry101 我后来才添加 enumerate 来测试它,否则通常的
for page in alexa_1000具有相同的效果。 -
是的,我的意思是在循环值的意义上“枚举”。之所以会出现这个常见问题是因为循环记得接下来提供
nth 项,并且删除较早的项会使项向下移动,因此位于collection[n]的项移动到collection[n-1]。一种解决方法是向后循环集合:for page in alexa_1000[::-1]:,因此将后面的项目向下移动不会干扰。另一种解决方法是制作一个临时副本,如 The for statement 中所述。 -
@Jerry101 非常感谢您的解释! :) 学到了很棒的东西。