【发布时间】:2014-04-25 16:56:10
【问题描述】:
我是一名 Python 程序员新手,我试图使用 Python 从 fanfiction.net 中抓取大量页面,并将页面 HTML 源代码的特定行存入 .csv 文件。我的程序运行良好,但最终遇到了停止运行的障碍。我的 IDE 告诉我程序遇到了“Errno 10054:现有连接被远程主机强行关闭”。
我正在寻找一种方法来让我的代码在每次收到错误时重新连接并继续。我的代码每次运行都会抓取几十万页;这对网站来说可能太多了吗?该网站似乎无法防止抓取。我已经对这个问题进行了大量研究并尝试实现重试装饰器,但装饰器似乎不起作用。这是我的代码的相关部分:
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
def deco_retry(f):
@wraps(f)
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries > 1:
try:
return f(*args, **kwargs)
except ExceptionToCheck as e:
msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
if logger:
logger.warning(msg)
else:
print(msg)
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
return f(*args, **kwargs)
return f_retry # true decorator
return deco_retry
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
def retrieveURL(URL):
response = urllib.request.urlopen(URL)
return response
def main():
# first check: 5000 to 100,000
MAX_ID = 600000
ID = 400001
URL = "http://www.fanfiction.net/s/" + str(ID) + "/index.html"
fCSV = open('buffyData400k600k.csv', 'w')
fCSV.write("Rating, Language, Genre 1, Genre 2, Character A, Character B, Character C, Character D, Chapters, Words, Reviews, Favorites, Follows, Updated, Published, Story ID, Story Status, Author ID, Author Name" + '\n')
while ID <= MAX_ID:
URL = "http://www.fanfiction.net/s/" + str(ID) + "/index.html"
response = retrieveURL(URL)
每当我在我的 IDE 之外运行 .py 文件时,它最终会在大约一个小时后锁定并停止抓取新页面。我还在我的 IDE 中运行同一文件的不同版本,而且现在似乎已经运行了将近 12 个小时,如果不是更长的话——该文件是否有可能在我的 IDE 中运行,但在独立运行时不能运行?
我的装饰器设置错了吗?我还能做些什么来让 python 重新连接?我还看到有人声称 SQL 本地客户端过时可能会给像我这样的 Window 用户带来问题——这是真的吗?我试图更新它,但没有运气。
谢谢!
【问题讨论】:
-
我认为提供的代码末尾的
while循环比您显示的要多,对吧?否则你有一个无限循环 -
是的!我不想发布整个内容,因为在 while 循环中,代码继续进行大量字符串格式化。我已经确认代码没有陷入任何无限循环,因为我有一个打印命令,指示代码何时检索到新 URL 并提取其 HTML。
-
附带说明,您可能需要查看Python Requests library。我发现它比 urllib 更容易使用。
标签: python html runtime-error screen-scraping