网站地图爬虫中永无止境的循环
never ending for loop in website mapping crawler
我正在做我的第一个 python 项目。我想制作一个访问网站以提取其所有链接(深度为 2)的爬虫。它应该将链接存储在两个列表中,形成一对一的寄存器,将源链接与它们包含的相应目标链接相关联。然后它应该创建一个包含两列(目标和源)的 csv 文件,这样我就可以用 gephi 打开它来创建一个显示站点地形结构的图表。
代码在代码执行部分的 for 循环处中断,它永远不会停止提取链接...(我尝试过一个相当小的博客,它永远不会结束)。问题是什么?我该如何解决?
需要考虑的几点:
- 我真的是编程新手 python 所以我意识到我的代码一定是非 pythonic。另外,由于我一直在寻找构建代码和解决我的问题的方法,所以它有点不完整,抱歉。感谢您的帮助!
myurl = raw_input("Introduce URL to crawl => ")
Dominios = myurl.split('.')
Dominio = Dominios[1]
#Variables Block 1
Target = []
Source = []
Estructura = [Target, Source]
links = []
#Variables Block 2
csv_columns = ['Target', 'Source']
csv_data_list = Estructura
currentPath = os.getcwd()
csv_file = "crawleo_%s.csv" % Dominio
# Block 1 => Extract links from a page
def page_crawl(seed):
try:
for link in re.findall('''href=["'](.[^"']+)["']''', urllib.urlopen(seed).read(), re.I):
Source.append(seed)
Target.append(link)
links.append(link)
except IOError:
pass
# Block 2 => Write csv file
def WriteListToCSV(csv_file, csv_columns, csv_data_list):
try:
with open(csv_file, 'wb') as csvfile:
writer = csv.writer(csvfile, dialect='excel', quoting=csv.QUOTE_NONNUMERIC)
writer.writerow(csv_columns)
writer.writerows(izip(Target, Source))
except IOError as (errno, strerror):
print("I/O error({0}): {1}".format(errno, strerror))
return
# Block 3 => Code execution
page_crawl(myurl)
seed_links = (links)
for sublink in seed_links: # Problem is with this loop
page_crawl(sublink)
seed_sublinks = (links)
## print Estructura # Line just to check if code was working
#for thirdlinks in seed_sublinks: # Commented out until prior problems are solved
# page_crawl(thirdlinks)
WriteListToCSV(csv_file, csv_columns, csv_data_list)
seed_links
和 links
指向同一个列表。因此,当您在 page_crawl
函数中向 links
添加元素时,您也在扩展 for 循环正在循环的列表。您需要做的是 clone the list 您创建 seed_links
.
的地方
这是因为 Python 通过引用传递对象。即多个变量可以不同名称指向同一个对象!
如果您想亲眼看到,请在 for 循环中尝试 print sublink
。您会注意到打印的链接比您最初输入的链接多。您可能还会注意到您正试图遍历整个网络 :-)
我没有立即看出哪里出了问题。然而,对此有几点评论:
- 您使用全局变量,这是不好的做法。您最好使用由 return.
传回的局部变量
- 第二层的link有没有可能指回第一层?这样你就有了数据循环。您需要为此做出规定以防止循环。所以你需要调查什么是 returned.
- 我会递归地实现它(使用前面的规定),因为这使代码更简单,尽管更抽象一些。
我正在做我的第一个 python 项目。我想制作一个访问网站以提取其所有链接(深度为 2)的爬虫。它应该将链接存储在两个列表中,形成一对一的寄存器,将源链接与它们包含的相应目标链接相关联。然后它应该创建一个包含两列(目标和源)的 csv 文件,这样我就可以用 gephi 打开它来创建一个显示站点地形结构的图表。
代码在代码执行部分的 for 循环处中断,它永远不会停止提取链接...(我尝试过一个相当小的博客,它永远不会结束)。问题是什么?我该如何解决?
需要考虑的几点: - 我真的是编程新手 python 所以我意识到我的代码一定是非 pythonic。另外,由于我一直在寻找构建代码和解决我的问题的方法,所以它有点不完整,抱歉。感谢您的帮助!
myurl = raw_input("Introduce URL to crawl => ")
Dominios = myurl.split('.')
Dominio = Dominios[1]
#Variables Block 1
Target = []
Source = []
Estructura = [Target, Source]
links = []
#Variables Block 2
csv_columns = ['Target', 'Source']
csv_data_list = Estructura
currentPath = os.getcwd()
csv_file = "crawleo_%s.csv" % Dominio
# Block 1 => Extract links from a page
def page_crawl(seed):
try:
for link in re.findall('''href=["'](.[^"']+)["']''', urllib.urlopen(seed).read(), re.I):
Source.append(seed)
Target.append(link)
links.append(link)
except IOError:
pass
# Block 2 => Write csv file
def WriteListToCSV(csv_file, csv_columns, csv_data_list):
try:
with open(csv_file, 'wb') as csvfile:
writer = csv.writer(csvfile, dialect='excel', quoting=csv.QUOTE_NONNUMERIC)
writer.writerow(csv_columns)
writer.writerows(izip(Target, Source))
except IOError as (errno, strerror):
print("I/O error({0}): {1}".format(errno, strerror))
return
# Block 3 => Code execution
page_crawl(myurl)
seed_links = (links)
for sublink in seed_links: # Problem is with this loop
page_crawl(sublink)
seed_sublinks = (links)
## print Estructura # Line just to check if code was working
#for thirdlinks in seed_sublinks: # Commented out until prior problems are solved
# page_crawl(thirdlinks)
WriteListToCSV(csv_file, csv_columns, csv_data_list)
seed_links
和 links
指向同一个列表。因此,当您在 page_crawl
函数中向 links
添加元素时,您也在扩展 for 循环正在循环的列表。您需要做的是 clone the list 您创建 seed_links
.
这是因为 Python 通过引用传递对象。即多个变量可以不同名称指向同一个对象!
如果您想亲眼看到,请在 for 循环中尝试 print sublink
。您会注意到打印的链接比您最初输入的链接多。您可能还会注意到您正试图遍历整个网络 :-)
我没有立即看出哪里出了问题。然而,对此有几点评论:
- 您使用全局变量,这是不好的做法。您最好使用由 return. 传回的局部变量
- 第二层的link有没有可能指回第一层?这样你就有了数据循环。您需要为此做出规定以防止循环。所以你需要调查什么是 returned.
- 我会递归地实现它(使用前面的规定),因为这使代码更简单,尽管更抽象一些。